0% нашли этот документ полезным (0 голосов)
11 просмотров622 страницы

RUS - MySQL Administrators Guide

Документ представляет собой руководство администратора по MySQL, изданное компанией MySQL AB и переведенное на русский язык. Книга охватывает установку, администрирование и оптимизацию сервера баз данных MySQL, а также предназначена для администраторов, разработчиков и студентов. Она содержит исчерпывающую информацию, включая вопросы безопасности, управление пользователями и механизмы хранения данных.

Загружено:

tooliks
Авторское право
© © All Rights Reserved
Мы серьезно относимся к защите прав на контент. Если вы подозреваете, что это ваш контент, заявите об этом здесь.
Доступные форматы
Скачать в формате PDF, TXT или читать онлайн в Scribd
0% нашли этот документ полезным (0 голосов)
11 просмотров622 страницы

RUS - MySQL Administrators Guide

Документ представляет собой руководство администратора по MySQL, изданное компанией MySQL AB и переведенное на русский язык. Книга охватывает установку, администрирование и оптимизацию сервера баз данных MySQL, а также предназначена для администраторов, разработчиков и студентов. Она содержит исчерпывающую информацию, включая вопросы безопасности, управление пользователями и механизмы хранения данных.

Загружено:

tooliks
Авторское право
© © All Rights Reserved
Мы серьезно относимся к защите прав на контент. Если вы подозреваете, что это ваш контент, заявите об этом здесь.
Доступные форматы
Скачать в формате PDF, TXT или читать онлайн в Scribd
Вы находитесь на странице: 1/ 622

M y S Q L

Руководаво администратора
M y S Q L

A d m i n i s t r a t o r ' s G u i d e

MySQLAB

M y S Q L
Press

800 East 96th Street, Indianapolis, Indiana 46240 USA


M y S Q L

Руководство администратора

Компания MySQL AB

Издательский дом "Вильяме"


Москва • Санкт-Петербург • Киев
2005
ББК 32.973.26-018.2.75
МП
УДК 681.3.07

Издательский дом "Вильяме"


Зав. редакцией С.Н. Тригуб

Перевод с английского Я.П. Волковой, Д.Я. Иваненко, НА. Мухина

Под редакцией Ю.Н. Артпеменко

По общим вопросам обращайтесь в Издательский дом "Вильяме"


по адресу: [email protected], http://www.williamspublishing.com
115419, Москва, а/я 783, 03150, Киев, а/я 152.

Компания MySQL AB.


МИ MySQL. Руководство администратора. : Пер. с англ. — М. : Издательский дом
"Вильяме", 2005. — 624 с. — Парал. тит. англ.
ISBN 5-8459-0805-1 (рус.)
Эта книга, написанная специалистами компании MySQL AB, является всеобъемлющим
справочником по установке, обслуживанию и администрированию сервера баз данных
MySQL. По сути — это официальная документация фирмы производителя. В книге рассмотрен
весь спектр вопросов, касающихся администрирования MySQL, а также представлена инфор-
мация, предназначенная для опытных пользователей и администраторов.
Как известно, MySQL занимает лидирующие позиции среди множества систем управления
базами данных с открытым исходным кодом. Благодаря высокой производительности и про-
стоте настройки, богатому выбору API-интерфейсов, а также функциональным средствам ра-
боты с сетями, сервер MySQL стал одним из наиболее удачных вариантов для разработки Web-
приложений, взаимодействующих с базами данных.
Книга рассчитана на администраторов и разработчиков Web-приложений любой квалифи-
кации, а также на студентов и преподавателей соответствующих дисциплин.

ББК 32.973.26-018.2.75

Вес названия программных продуктов являются зарегистрированными торговыми марками соответствую-


щих фирм.
Никакая часть настоящего издания ни в каких целях не может быть воспроизведена в какой бы то ни было
форме и какими бы то ни было средствами, будь то электронные или механические, включая фотокопирование
и запись на магнитный носитель, если на это нет письменного разрешения издательства MySQL Press.

Authorized translation from the English language edition published by MySQL Press, Copyright © 2004
All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic
or mechanical, including photocopying, recording or by any information storage retrieval system, without permission
from the Publisher.
Russian language edition published by Williams Publishing House according to the Agreement with R&I
Enterprises International, Copyright © 2005

ISBN 5-8459-0805-1 (рус.) © Издательский дом "Вильяме", 2005


ISBN 0-672-32634-5 (англ.) © MySQL AB, 2004
Оглавление

Об этой книге 14
От издательства 14
Глава 1. Общая информация 15
Глава 2. Установка MySQL 76
Глава 3. Использование программ MySQL 202
Глава 4. Администрирование баз данных 212
Глава 5. Репликация в MySQL 365
Глава 6. Оптимизация MySQL 402
Глава 7. Клиентские программы и утилиты MySQL 460
Глава 8. Механизмы хранения и типы таблиц в MySQL 498
Глава 9. Механизм хранения InnoDB 523
Глава 10. Введение в MaxDB 582
Приложение А. Поиск и устранение неполадок в программах MySQL 588
Приложение Б. Переменные окружения 612
Предметный указатель 614
Содержание

Об этой книге 14
От издательства 14
Глава 1. Общая информация 15
1.1. Что собой представляет это руководство 15
1.1.1. Соглашения, используемые в руководстве 16
1.2. Что такое система управления базами данных MySQL 18
1.2.1. История MySQL 19
1.2.2. Основные возможности MySQL 20
1.2.3. Стабильность MySQL 22
1.2.4. Размеры таблиц MySQL 23
1.2.5. Решение "проблемы 2000 года" 25
1.3. Компания MySQL AB 26
1.3.1. Бизнес-модель и услуги, оказываемые MySQL AB 27
1.3.2. Контактная информация 30
1.4. Поддержка и лицензирование MySQL 31
1.4.1. Поддержка, предоставляемая компанией MySQL AB 31
1.4.2. Авторские права и лицензии на MySQL 32
1.4.3. Лицензии на MySQL 32
1.4.4. Логотипы и торговые марки MySQL AB 35
1.5. План разработки MySQL 37
1.5.1. Кратко о MySQL 4.0 37
1.5.2. Кратко о MySQL 4.1 39
1.5.3. MySQL 5.0: Очередной разрабатываемый выпуск 41
1.6. MySQL и будущее (списки TODO) 41
1.6.1. Новые средства, запланированные для версии 4.1 41
1.6.2. Новые средства, запланированные для версии 5.0 42
1.6.3. Новые средства, запланированные для версии 5.1 43
1.6.4. Новые средства, запланированные на ближайшее будущее 43
1.6.5. Новые средства, запланированные на отдаленное будущее 46
1.6.6. Новые средства, которые не планируются к реализации 47
1.7. Источники информации по MySQL 48
1.7.1. Списки рассылки MySQL 48
1.7.2. Поддержка сообщества пользователей MySQL в IRC 56
1.8. Соответствие стандартам MySQL 56
1.8.1. Стандарты, которым соответствует MySQL 57
1.8.2. Выбор режимов SQL 57
1.8.3. Запуск MySQL в режиме ANSI 57
1.8.4. Расширения стандартного SQL в MySQL 58
1.8.5. Отличия MySQL от стандартного SQL 61
1.8.6. Как MySQL работает с ограничениями 68
1.8.7. Известные ошибки и недостатки дизайна MySQL 70
Содержание 7

Глава 2. Установка MySQL 76


2.1. Общие вопросы установки 77
2.1.1. Операционные системы, поддерживаемые MySQL 77
2.1.2. Выбор дистрибутива MySQL для установки 79
2.1.3. Как получить MySQL 90
2.1.4. Проверка целостности пакета с помощью контрольных
сумм MD5 или GnuPG 90
2.1.5. Расположение каталогов установки 93
2.2. Стандартная установка MySQL из бинарного дистрибутива 95
2.2.1. Установка MySQL под Windows 95
2.2.2. Установка MySQL под Linux 107
2.2.3. Установка MySQL под Mac OS X 109
2.2.4. Установка MySQL под NetWare 112
2.2.5. Установка MySQL в других Unix-подобных системах 114
2.3. Установка MySQL из исходного дистрибутива 117
2.3.1. Обзор установки из исходного дистрибутива 118
2.3.2. Типичные опции сценария configure 121
2.3.3. Установка из исходного дерева разработки 124
2.3.4. Решение проблем компиляции MySQL 127
2.3.5. Замечания по поводу потоков MIT-pthreads 131
2.3.6. Установка MySQL из исходных дистрибутивов под Windows 133
2.3.7. Компиляция клиентских программ MySQL под Windows 136
2.4. Настройки и тестирование после установки 136
2.4.1. Постустановочные процедуры под Windows 137
2.4.2. Постустановочные процедуры под Unix 138
2.4.3. Автоматический запуск и останов MySQL 144
2.4.4. Запуск сервера MySQL и устранение неисправностей 146
2.4.5. Защита начальных учетных записей MySQL 149
2.5. Модернизация MySQL и возврат к старой версии 153
2.5.1. Модернизация версии 4.1 до 5.0 154
2.5.2. Модернизация версии 4.0 до 4.1 154
2.5.3. Модернизация версии 3.23 до 4.0 159
2.5.4. Модернизация версии 3.22 до 3.23 163
2.5.5. Модернизация версии 3.21 до 3.22 165
2.5.6. Модернизация версии 3.20 до 3.21 166
2.5.7. Модернизация MySQL под Windows 167
2.5.8. Обновление таблиц привилегий 167
2.5.9. Копирование баз данных MySQL на другую машину 168
2.6. Замечания по поводу конкретных операционных систем 170
2.6.1. Замечания по поводу Linux 170
2.6.2. Замечания по Max OS X 178
2.6.3. Замечания по Solaris 179
2.6.4. Замечания по BSD 183
2.6.5. Замечания по другим системам Unix 187
2.6.6. Замечания по OS/2 196
2.6.7. Замечания по BeOS 197
2.7. Замечания по поводу установки Perl 197
2.7.1. Установка Perl под Unix 197
8 Содержание

2.7.2. Установка ActiveState Perl под Windows 198


2.7.3. Проблемы использования интерфейса Perl DBI/DBD 199
Глава 3. Использование программ MySQL 202
3.1. Обзор программ MySQL 202
3.2. Запуск MySQL-программ 203
3.3. Задание опций программы 204
3.3.1. Использование опций в командной строке 204
3.3.2. Использование файлов опций 206
3.3.3. Использование переменных окружения для задания опций 210
3.3.4. Использование опций для установки программных переменных 210
Глава 4. Администрирование баз данных 212
4.1. Сервер MySQL и сценарии запуска сервера 212
4.1.1. Обзор серверных сценариев и утилит 212
4.1.2. Расширенный MySQL-сервер mysqld-max 213
4.1.3. Сценарий запуска сервера mysqld_safe 215
4.1.4. Сценарий запуска сервера mysql.server 218
4.1.5. Программа mysqldmulti для управления множественными
MySQL-серверами 219
4.2. Конфигурирование сервера MySQL 223
4.2.1. Опции командной строки mysqld 223
4.2.2. Режим SQL сервера 232
4.2.3. Системные переменные сервера 234
4.2.4. Переменные состояния сервера 260
4.3. Общие проблемы безопасности 265
4.3.1. Общие принципы, касающиеся безопасности системы 265
4.3.2. Как защитить MySQL от хакеров 268
4.3.3. Опции запуска для mysqld, касающиеся безопасности 270
4.3.4. Вопросы безопасности и оператор LOAD DATA LOCAL 271
4.4. Система привилегий доступа MySQL 272
4.4.1. Функции системы привилегий 272
4.4.2. Как работает система привилегий 273
4.4.3. Привилегии, предоставляемые MySQL 277
4.4.4. Подключение к серверу MySQL 281
4.4.5. Управление доступом, этап первый: верификация подключения 282
4.4.6. Управление доступом, этап второй: верификация запросов 286
4.4.7. Когда изменения в привилегиях вступают в силу 289
4.4.8. Причины появления ошибок отказа в доступе (Access denied) 289
4.4.9 Хеширование паролей в MySQL 4.1 295
4.5. Управление учетными записями пользователей MySQL 301
4.5.1. Имена пользователей и пароли в MySQL 301
4.5.2. Добавление новых учетных записей в MySQL 303
4.5.3. Удаление пользовательских учетных записей из MySQL 306
4.5.4. Ограничение ресурсов учетной записи 307
4.5.5. Назначение паролей для учетных записей 309
4.5.6. Как обезопасить свой пароль 310
4.5.7. Использование безопасных соединений 311
4.6. Предотвращение аварий и восстановление системы 318
Содержание 9

4.6.1. Резервное копирование баз данных 318


4.6.2. Обслуживание и восстановление таблиц после аварий 320
4.6.3. Установка графика обслуживания таблиц 333
4.6.4. Как получить информацию о таблице 334
4.7. Локализация MySQL и интернациональное применение 340
4.7.1. Набор символов для представления данных и сортировки 340
4.7.2. Установка языка сообщений об ошибках 341
4.7.3. Добавление нового набора символов 342
4.7.4. Массивы определения символов 343
4.7.5. Поддержка функций по упорядочиванию строк 344
4.7.6. Поддержка многобайтных символов 344
4.7.7. Проблемы с наборами символов 344
4.8. Журнальные файлы MySQL 345
4.8.1. Журнал ошибок 346
4.8.2. Общий журнал запросов 346
4.8.3. Журнал регистрации обновлений 347
4.8.4. Бинарный журнал регистрации 348
4.8.5. Журнал медленных запросов 351
4.8.6. Обслуживание журнальных файлов 351
4.9. Запуск нескольких серверов MySQL на одном и том же компьютере 352
4.9.1. Запуск нескольких серверов в Windows 354
4.9.2. Запуск нескольких серверов под Unix 358
4.9.3. Использование клиентских программ в окружении
с несколькими серверами 359
4.10. Кэш запросов MySQL 360
4.10.1. Как работает кэш запросов 361
4.10.2. Опции SELECT для кэша запросов 362
4.10.3. Конфигурирование кэша запросов 362
4.10.4. Состояние кэша запросов и его обслуживание 363
Глава 5. Репликация в MySQL 365
5.1. Введение в репликацию 365
5.2. Обзор реализации репликации 366
5.3. Детали реализации процесса репликации 367
5.3.1. Состояние потока репликации главного сервера 369
5.3.2. Состояние потока репликации ввода/вывода подчиненного сервера 369
5.3.3. Состояние потока SQL репликации подчиненного сервера 371
5.3.4. Журнал ретрансляции и файлы состояния 371
5.4. Настройка репликации 373
5.5. Совместимость репликации между версиями MySQL 378
5.6. Модернизация установок репликации 378
5.6.1. Модернизация репликации до версии 4.0 или 4.1 379
5.6.2. Модернизация репликации до версии 5.0 379
5.7. Возможности репликации и известные проблемы 380
5.8. Опции запуска репликации 384
5.9. Часто задаваемые вопросы по репликации 393
5.10. Поиск неисправностей в системе репликации 399
5.11. Сообщения об ошибках репликации 400
10 Содержание

Глава 6. Оптимизация MySQL 402


6.1. Обзор оптимизации 402
6.1.1. Ограничения и компромиссы конструкции MySQL 403
6.1.2. Проектирование переносимых приложений 403
6.1.3. Для чего мы использовали MySQL 405
6.1.4. Набор тестов производительности MySQL 405
6.1.5. Использование собственных тестов производительности 406
6.2. Оптимизация операторов SELECT и других запросов 407
6.2.1. Синтаксис оператора EXPLAIN (получение информации о SELECT) 408
6.2.2. Ожидаемая производительность запросов 415
6.2.3. Скорость выполнения запросов SELECT 416
6.2.4. Как MySQL оптимизирует конструкцию WHERE 416
6.2.5. Как MySQL оптимизирует выражения OR 418
6.2.6. Как MySQL оптимизирует IS NULL 419
6.2.7. Как MySQL оптимизирует DISTINCT 419
6.2.8. Как MySQL оптимизирует LEFT JOIN и RIGHT JOIN 420
6.2.9. Как MySQL оптимизирует ORDER BY 421
6.2.10. Как MySQL оптимизирует LIMIT 423
6.2.11. Как избежать сканирования таблиц 424
6.2.12. Скорость выполнения запросов INSERT 424
6.2.13. Скорость выполнения запросов UPDATE 426
6.2.14. Скорость выполнения запросов DELETE 427
6.2.15. Другие советы по оптимизации 427
6.3. Вопросы блокировки 430
6.3.1. Методы блокировки 430
6.3.2. Вопросы блокировки таблиц 433
6.4. Оптимизация структуры базы данных 435
6.4.1. Конструкторские решения 435
6.4.2. Делайте объем данных как можно меньше 435
6.4.3. Индексы столбцов 436
6.4.4. Составные индексы 437
6.4.5. Как MySQL использует индексы 438
6.4.6. Кэш ключей MylSAM 441
6.4.7. Как MySQL подсчитывает открытые таблицы 446
6.4.8. Как MySQL открывает и закрывает таблицы 446
6.4.9. Недостатки создания множества таблиц в одной базе данных 447
6.5. Оптимизация сервера MySQL 448
6.5.1. Настройка параметров системы и запуска 448
6.5.2. Настройка параметров сервера 449
6.5.3. Как компиляция и компоновка влияют на скорость MySQL 451
6.5.4. Как MySQL использует память 453
6.5.5. Как MySQL использует DNS 454
6.6. Вопросы использования дисков 455
6.6.1. Использование символических ссылок 456
Глава 7. Клиентские программы и утилиты MySQL 460
7.1. Обзор сценариев и утилит клиентской стороны 460
Содержание 11

7.2. myisampack - генератор сжатых таблиц MySQL,


доступных только для чтения 461
7.3. Инструмент командной строки mysql 467
7.3.1. Команды mysql 471
7.3.2. Запуск SQL-операторов из текстового файла 475
7.3.3. Советы по mysql 476
7.4. Программа администрирования MySQL-сервера mysqladmin 477
7.5. Утилита работы с бинарными журналами mysqlbinlog 480
7.6. Центр управления MySQL - mysqlcc 483
7.7. Программа обслуживания и восстановления таблиц mysqlcheck 485
7.8. Программа резервного копирования баз данных mysqldump 487
7.9. Программа резервного копирования базы данных mysqhotcopy 492
7.10. Программа импорта данных mysqlimport 493
7.11. Программа просмотра баз данных, таблиц и столбцов mysqlshow 495
7.12. Утилита объяснения кодов ошибок реггог 497
7.13. Утилита замены строк replace 497
Глава 8. Механизмы хранения и типы таблиц в MySQL 498
8.1. Механизм хранения My IS AM 500
8.1.1. Опции запуска MylSAM 502
8.1.2. Пространство, необходимое для ключей 504
8.1.3. Форматы хранения данных в таблицах MylSAM 504
8.1.4. Проблемы, связанные с таблицами MylSAM 507
8.2. Механизм хранения MERGE 509
8.2.1. Проблемы, связанные с таблицами MERGE 511
8.3. Механизм хранения данных MEMORY (HEAP) 513
8.4. Механизм хранения данных BDB (BerkleyDB) 515
8.4.1. Операционные системы, поддерживающие BDB 516
8.4.2. Установка BDB 516
8.4.3. Опции запуска BDB 517
8.4.4. Характеристики таблиц BDB 517
8.4.5. Что должно быть исправлено в механизме хранения BDB 520
8.4.6. Ограничения при использовании таблиц BDB 520
8.4.7. Ошибки, которые могут возникать при использовании таблиц BDB 520
8.5. Механизм хранения ISAM 521
Глава 9. Механизм хранения InnoDB 523
9.1. Обзор InnoDB 523
9.2. Контактная информация, касающаяся InnoDB 524
9.3. Таблицы InnoDB в MySQL 3.23 524
9.4. Конфигурация InnoDB 525
9.5. Опции запуска InnoDB 530
9.6. Создание табличного пространства InnoDB 534
9.6.1. Проблемы, связанные с инициализацией InnoDB 535
9.7. Создание таблиц InnoDB 535
9.7.1. Как использовать транзакции InnoDB в разных API-интерфейсах 536
9.7.2. Преобразование таблиц MylSAM в формат InnoDB 537
9.7.3. Как работают столбцы AUTOJNCREMENT в InnoDB 538
9.7.4. Ограничения внешнего ключа (FOREIGN KEY) 539
12 Содержание

9.7.5. InnoDB и репликация в MySQL 543


9.7.6. Использование табличного пространства для каждой таблицы 544
9.8. Добавление и удаление файлов данных и файлов журналов InnoDB 546
9.9. Создание резервных копий и восстановление базы данных InnoDB 547
9.9.1. Принудительное восстановление 548
9.9.2. Контрольные точки 550
9.10. Перенос базы данных InnoDB на другой компьютер 550
9.11. Транзакционная модель InnoDB и блокирование 551
9.11.1. InnoDB и режим автоматической фиксации AUTOCOMMIT 551
9.11.2. InnoDB и уровень изоляции транзакций
(TRANSACTION ISOLATION LEVEL) 551
9.11.3. Согласованное чтение без блокировки 553
9.11.4. Чтения с блокировкой: SELECT... FOR UPDATE
и SELECT... LOCK IN SHARE MODE 554
9.11.5. Блокировка следующего ключа: устранение "проблемы с фантомом" 555
9.11.6. Пример работы согласованного чтения в InnoDB 556
9.11.7. Блокировка, устанавливаемая различными
SQL-операторами в InnoDB 557
9.11.8. В каких случаях MySQL явно выполняет фиксацию
или откат транзакции 558
9.11.9. Обнаружение взаимных блокировок и откат 559
9.11.10. Как справляться с взаимными блокировками 559
9.12. Советы по настройке производительности InnoDB 561
9.12.1. SHOW INNODB STATUS и мониторы InnoDB 563
9.13. Реализация многовариантности 568
9.14. Структуры таблиц и индексов 568
9.14.1. Физическая структура индекса 569
9.14.2. Буферизация вставок 569
9.14.3. Адаптивный хешированный индекс 570
9.14.4. Физическая структура записи 570
9.15. Управление файловым пространством и дисковый ввод-вывод 571
9.15.1. Дисковый ввод-вывод 571
9.15.2. Использование низкоуровневых устройств
для табличного пространства 572
9.15.3. Управление файловым пространством 572
9.15.4. Дефрагментация таблицы 573
9.16. Обработка ошибок 574
9.16.1. Коды ошибок InnoDB 574
9.16.2. Коды ошибок операционной системы 575
9.17. Ограничения таблиц InnoDB 577
9.18. Поиск и устранение неполадок в InnoDB 579
9.18.1. Поиск и устранение неполадок в операциях словаря данных InnoDB 580
Глава 10. Введение в MaxDB 582
10.1. История MaxDB 582
10.2. Лицензирование и поддержка 582
10.3. Ссылки, касающиеся MaxDB 583
10.4. Базовые концепции MaxDB 583
10.5. Отличия возможностей MaxDB и MySQL 583
Содержание 13

10.6. Средства взаимодействия между MaxDB и MySQL 584


10.7. Зарезервированные слова MaxDB 584
Приложение А. Поиск и устранение неполадок в программах MySQL 588
АЛ. Как определить причину проблемы 588
А.2. Наиболее общие ошибки при работе с программами MySQL 590
А.2.1. Доступ запрещен 590
А.2.2.Невозможно подключиться к [локальному] серверу MySQL 590
А.2.3. Клиент не поддерживает протокол аутентификации 592
А.2.4. Пароль не принимается при интерактивном вводе 593
А.2.5. Хост 'имяхоста' заблокирован 593
А.2.6. Слишком много подключений 594
А.2.7. Недостаточно памяти 594
А.2.8. Сервер MySQL потерян 594
А.2.9. Слишком большой пакет 595
А.2.10. Ошибки связи и прерванные соединения 597
А.2.11. Переполнение таблицы 598
А.2.12. Невозможно создать/записать файл 598
А.2.13. Команды не синхронизированы 599
А.2.14. Игнорируется пользователь 599
А.2.15. Таблица 'имятаблицы' не существует 599
А.2.16. Невозможно инициализировать набор символов 600
А.2.17. Файл не найден 600
А.З. Вопросы, связанные с установкой 601
А.3.1. Проблемы компоновки клиентской библиотеки MySQL 601
А.З.2. Как запускать MySQL от имени обычного пользователя 603
А.3.3. Проблемы с правами доступа к файлам 603
А.4. Вопросы, касающиеся администрирования 604
А.4.1. Как сбросить пароль для root 604
А.4.2. Что делать, если MySQL терпит крах 606
А.4.3. Как MySQL обрабатывает переполнение диска 609
А.4.4. Где MySQL хранит временные файлы 609
А.4.5. Как защитить или изменить файл сокета MySQL /tmp/mysql.sock 610
А.4.6. Проблемы с временными зонами 611
Приложение Б. Переменные окружения 612
Предметный указатель 614
Об этой книге
Исходными материалами для этой книги послужили разделы онлайновой документа-
ции по MySQL (http://www.mysql.com), посвященные вопросам установки, обслужива-
ния и администрирования сервера баз данных MySQL. Книга представляет собой полез-
ный и полный справочник по всему спектру вопросов, от установки до репликации, от
оптимизации базы данных до хитросплетений механизма хранения InnoDB.
Первоначально это руководство было написано Майклом Монти Видениусом
(Michael "Monty" Widenius) и Дэвидом Аксмарком (David Axmark), а теперь его под-
держкой занимается группа разработки документации по MySQL.
Большой вклад в подготовку данной книги внесли Поль Дюбуа (Paul DuBois), Стефан
Хинц (Stefan Hinz) и Аржен Ленц (Arjen Lentz) из группы разработки документации.

От издательства
Вы, читатель этой книги, и есть главный ее критик и комментатор. Мы ценим ваше
мнение и хотим знать, что было сделано нами правильно, что можно было сделать луч-
ше и что еще вы хотели бы увидеть изданным нами. Нам интересно услышать и любые
другие замечания, которые вам хотелось бы высказать в наш адрес.
Мы ждем ваших комментариев и надеемся на них. Вы можете прислать нам бумаж-
ное или электронное письмо, либо просто посетить наш Web-сервер и оставить свои за-
мечания там. Одним словом, любым удобным для вас способом дайте нам знать, нравит-
ся или нет вам эта книга, а также выскажите свое мнение о том, как сделать наши книги
более интересными для вас.
Посылая письмо или сообщение, не забудьте указать название книги и ее авторов, а
также ваш обратный адрес. Мы внимательно ознакомимся с вашим мнением и обяза-
тельно учтем его при отборе и подготовке к изданию последующих книг.
Наши координаты:
E-mail: [email protected]
WWW: http: //www.williamspublishing.com
Информация для писем из:
России: 115419, Москва, а/я 783
Украины: 03150, Киев, а/я 152
1
Общая информация

П рограммное обеспечение MySQL® представляет собой очень быстрый, многопо-


точный, многопользовательский и надежный сервер баз данных SQL (Structured
Query Language - язык структурированных запросов). Сервер MySQL предназначен как
для обслуживания критически важных, сильно загруженных производственных систем,
так и для встраивания в программное обеспечение массового применения. MySQL - тор-
говая марка, принадлежащая MySQL AB.
Программное обеспечение MySQL распространяется в соответствие с двойной ли-
цензией (Dual License). Пользователь может использовать его либо как бесплатный про-
дукт с открытым исходным кодом (Open Source/Free Software) на условиях общедоступ-
ной лицензии GNU General Public License, либо приобрести стандартную коммерческую
лицензию у MySQL AB. Дополнительную информацию можно найти в разделе 1.4.
Актуальная информация о программном обеспечении MySQL доступна на Web-сайте
MySQL (http: //www. mysql. com/).

1.1. Что собой представляет это руководство


Настоящее руководство составлено на основании тех разделов справочного руково-
дства по MySQL (MySQL Referense Guide), которые посвящены вопросам администриро-
вания баз данных. Здесь описывается установка программного обеспечения, конфигури-
рование сервера, ежедневные операции по обслуживанию, поддержке таблиц и реплика-
ции данных. Сопутствующая книга, "MySQL. Справочник по языку " ("MySQL Language
Reference"), служит справочником по языку SQL, используемому для выполнения запро-
сов к базам данных MySQL. В нем описываются языковые конструкции, функции и опе-
рации, типы данных столбцов таблиц и синтаксис операторов SQL.
Это руководство касается MySQL 5.0.1, но также применимо и к более старым верси-
ям MySQL (таким как 3.23 или 4.0), поскольку функциональные изменения между вер-
сиями специальным образом отмечаются.
Поскольку настоящее руководство служит справочником, оно не включает в себя
общие сведения об SQL и концепциях реляционных баз данных. Оно также не обучает
работе с операционной системой или интерпретатором командной строки.
Программное обеспечения баз данных MySQL постоянно развивается, и его справоч-
ное руководство обновляется настолько часто, насколько это возможно. Последняя вер-
сия руководства доступна в Internet по адресу http://dev.mysql.com/doc/ в различных
форматах, включая HTML, PDF и Windows CHM.
16 Глава 1. Общая информация

Если у вас есть предложения, касающиеся любых дополнений и исправлений на-


стоящего руководства, пожалуйста, присылайте их группе, занятой созданием докумен-
тации, по адресу docs@mysql. com.
Первоначально это руководство было написано Дэвидом Аксмарком (David Axmark)
и Майклом Монти Видениусом (Michael "Monty" Widenius). Теперь его поддержкой за-
нимается группа разработки документации по MySQL (MySQL Documentation Team), в
состав которой входят Аржен Ленц (Arjen Lentz), Поль Дюбуа (Paul DuBois) и Стефан
Хинц (Stefan Hinz).
Авторские права на это руководство (2004 год) принадлежат шведской компании
MySQL AB (см. раздел 1.4.2).

1.1.1. Соглашения, используемые в руководстве


В настоящем руководстве приняты следующие типографские соглашения:
• моноширинный
Моноширинным шрифтом представляются имена и опции команд, SQL-
операторы, имена баз данных, таблиц и столбцов, код на языках С и Perl, имена
файлов и переменных окружения, а также URL-адреса. Например: "Чтобы уви-
деть, как работает mysqladmin, запустите его с опцией —help".
• моноширинный с полужирным начертанием
С помощью моноширинного шрифта с полужирным начертанием обозначается
пользовательского ввод в примерах.
• моноширинный с курсивным начертанием
Моноширинный шрифт с курсивным начертанием используется для обозначения
ввода изменяющейся информации, когда пользователь должен подставлять то или
иное значение.
• 'с1
Моноширинный шрифт и одинарные кавычки применяются для задания последо-
вательностей символов, например: "Для определения шаблона используйте сим-
вол • %'".
• курсив
С помощью курсива выделяются важные слова и фраза, например, так.
• полужирный
Шрифт с полужирным начертанием используется для заголовков таблиц, а также
для выделения особо важных фраз.
Когда необходимо показать команды, которые выполняются в среде какой-либо про-
граммы, перед командами помещается специальное приглашение. Например, shell>
обозначает, что команда запускается в среде оболочки, a mysql> показывает, что опера-
тор выполняется с помощью клиентской программы mysql.
shell> введите команду оболочки
mysql> введите оператор mysql
Здесь через "shell" обозначен используемый вами командный интерпретатор. В UNIX
это обычно программа, подобная sh или csh. Эквивалентными программами в Windows
являются command.exe или cmd.exe, обычно запускаемые в окне консоли.
1.1. Что собой представляет это руководство 17

При вводе команды или оператора, показанного в примере, приглашение вводить не


нужно.
В приведенном выше примере пользовательский ввод представлен полужирным на-
чертанием. Изменяющаяся информация, вместо которой нужно подставлять выбранное
вами значение, выделяется курсивным начертанием. Имена баз данных, таблиц и их
столбцов часто подставляются в аргументы операторов. В настоящем руководстве такие
подстановки обязательно выделяются: имя_БДу имя_таблицы, имя_столбца. Например, вы
можете встретить в книге что-нибудь такое:
mysql> SELECT имя_столбца FROM имя_БД.имя_таблицы;
Это означает, что при вводе подобного оператора потребуется указать реальные име-
на базы данных, таблицы и столбца, например, следующим образом:
mysql> SELECT author_name FROM biblio_db.author_list;
Ключевые слова SQL нечувствительны к регистру, то есть их можно вводить как за-
главными, так и прописными буквами. В настоящем руководстве ключевые слова пред-
ставлены заглавными буквами.
В описаниях синтаксиса для обозначения необязательных слов или конструкций ис-
пользуются квадратные скобки (' [' и ' ] ' ) . В приведенном ниже примере IF EXISTS явля-
ется необязательной частью выражения:
DROP TABLE [IF EXISTS] имя_таблицы;
Когда элемент синтаксиса предусматривает несколько альтернатив, они разделяются
с помощью вертикальной черты ('Г). Если из набора возможных альтернатив может
быть выбран один элемент, последовательность вариантов помещается в квадратные
скобки:
TRIM [[BOTH | LEADING | TRAILING] [ост_строка] FROM строка];
В случае если из набора возможных альтернатив должен быть выбран один элемент,
альтернативные варианты перечисляются в фигурных скобках:
{DESCRIBE | DESC} имя_таблицы [имя_столбца \ групповой_символ];
С помощью троеточия ( . . . ) обозначается пропущенная часть выражения; это позво-
ляет сократить представление сложного синтаксиса. Например, INSERT... SELECT пред-
ставляет собой сокращенную форму записи оператора INSERT и следующего за ним опе-
ратора SELECT.
Троеточие также означает, что предшествующий элемент синтаксиса может повто-
ряться. В следующем примере можно задать множество значений опция_сброса, каждое
из которых, кроме первого, предваряется запятой:
RESET опция_сброса [, опция_сброса] ...

Команды установки значения переменных оболочки представлены в соответствие с


синтаксисом оболочки Bourne. Например, последовательность, устанавливающая значе-
ние переменной оболочки и запускающая команду, выглядит следующим образом:
s h e l l > ИМЯ_ПЕРЕМЕННОЙ=значение команда
Если используется csh или tcsh, команды вводятся по-другому. Приведенная выше
последовательность будет выглядеть так:
s h e l l > setenv ИМЯ_ПЕРЕМЕННОЙ значение
s h e l l > команда
18 Глава 1. Общая информация

1.2. Что такое система управления базами


данных MySQL
Разработкой, распространением и поддержкой MySQL, наиболее популярной систе-
мы управления базами данных (СУБД) с открытым исходным кодом, занимается компа-
нией MySQL AB.
MySQL AB - коммерческая компания, основанная разработчиками MySQL, строит
свой бизнес на предоставлении услуг, так или иначе связанных с СУБД MySQL. Более
подробную информацию о компании MySQL AB можно найти в разделе 1.3.
Кроме того, на сайте MySQL (http://www.mysql.com/) представлена наиболее акту-
альная информация о СУБД MySQL и компании MySQL AB.
• MySQL - это система управления базами данных.
База данных представляет собой структурированный набор данных. Она может
содержать различную информацию - от простого списка покупок до огромного
объема данных, используемого в корпоративной сети.
• MySQL - это система управления реляционными базами данных.
Реляционная база данных хранит информацию в отдельных таблицах, а не в од-
ном большом хранилище, благодаря чему достигается высокая производитель-
ность и гибкость. Часть "SQL" слова "MySQL" обозначает "Structured Query
Language" ("Язык структурированных запросов"). SQL - наиболее общий стан-
дартизованный язык доступа к базам данных; он соответствует стандарту
ANSI/ISO SQL. Стандарт SQL впервые был принят в 1986 году и на настоящее
время существует несколько его версий. В настоящем руководстве "SQL-92" ссы-
лается на стандарт, принятый в 1992 году, "SQL: 1999" - на стандарт, принятый в
1999 году, и "SQL:2003" - на текущую версию стандарта. В дальнейшем под
"стандартом SQL" имеется в виду текущая версия данного стандарта.
• MySQL - это система с открытым исходным кодом.
Открытость исходного кода означает, что любой желающий имеет возможность
использовать и модифицировать это программное обеспечение по своему усмот-
рению. Получить и развернуть программное обеспечение MySQL можно из
Internet, причем совершенно бесплатно. Каждый пользователь, при желании, мо-
жет изучить исходные тексты и изменить их в соответствии со своими потребно-
стями. Программное обеспечение MySQL распространяется по лицензии GPL
(GNU General Public License), которая регламентирует, что разрешено, а что нет в
отношении программного обеспечения. Если по тем или иным причинам лицен-
зия GPL не устраивает либо код MySQL требуется встраивать в коммерческие
приложения, следует приобрести коммерческую лицензированную версию у ком-
пании MySQL AB (см. раздел 1.4.3).
• Сервер баз данных MySQL - очень быстрый, надежный и простой в эксплуатации
сервер.
Если это как раз то, что вы ищете, стоит с ним поработать. Сервер MySQL вклю-
чает в себя практичный набор средств, разработанных в тесной кооперации с со-
обществом пользователей. Результаты сравнительных тестов производительности
MySQL и других СУБД доступны по адресу http://dev.mysql.com/tech-
resources/crash-me.php. Изначально сервер MySQL был разработан для более
быстрого управления большими базами данных, чем существующие решения в
1.2. Что такое система управления базами данных MySQL 19

этой области, и на протяжении ряда лет успешно эксплуатировался в средах, к ко-


торым предъявлялись весьма высокие требования. Несмотря на то что MySQL
пребывает в непрекращающемся процессе разработки, на сегодняшний день он
предоставляет богатый набор удобных в эксплуатации средств и функций. При-
сущие серверу MySQL возможности сетевого взаимодействия, производитель-
ность и безопасность делают его удачным вариантом для работы с базами данных
в Internet.
• Сервер MySQL работает в клиент-серверных и встроенных системах.
СУБД MySQL является клиент-серверной системой, включающей многопоточный
SQL-сервер, поддерживающий различные платформы, несколько клиентских про-
грамм и библиотек, инструменты администрирования и широкий диапазон про-
граммных интерфейсов приложений (API-интерфейсов).
Сервер MySQL существует также и в форме встраиваемое многопоточной биб-
лиотеки, которую можно связывать с разрабатываемыми приложениями, чтобы
получить более компактные, быстрые и легкоуправляемые продукты.
• Доступен огромный объем программного обеспечения MySQL, написанного неза-
висимыми разработчиками.
Весьма вероятно, что предпочитаемое вами приложение и язык уже поддержива-
ют сервер баз данных MySQL.
"MySQL" произносится как "май-эс-кю-эл" (а не "май-сиквел"), однако никто не
против, если вы будете произносить название "MySQL" как вам заблагорассудится.

1.2.1. История MySQL


Все началось с намерения подключиться с помощью mSQL к нашим таблицам данных,
используя наши собственные низкоуровневые (ISAM) процедуры. Не особо долгое тес-
тирование показало, что mSQL не обладает достаточной производительностью и гибко-
стью, дабы полностью удовлетворить существующие у нас требования. В итоге был соз-
дан новый SQL-интерфейс к нашей базе данных, который обладал почти таким же API-
интерфейсом, что и mSQL. Этот API-интерфейс был разработан так, чтобы существенно
упростить перенос кода независимых разработчиков, ориентированного на взаимодейст-
вие с mSQL, на новую платформу, связанную с MySQL.
Происхождение наименования "MySQL" неоднозначно. Наименования нашего базо-
вого каталога и огромного количества библиотек и инструментов имели префикс " т у " в
течение более 10 лет. С другой стороны, дочку одного из наших соучредителей, Монти
Видениуса (Monty Widenius), тоже звали Май (My). Какое именно из этих двух обстоя-
тельств стало причиной появления наименования MySQL - до сих пор является тайной
за семью печатями, даже для нас.
Кличка дельфина MySQL, изображенного на нашем логотипе - Сакила (Sakila) - бы-
ла выбрана основателями компании MySQL AB из большого списка кличек, предложен-
ных пользователями в процессе дискуссии "Дайте кличку дельфину". Победила кличка,
предложенная Эмброузом Твибейзом (Ambrose Twebaze), разработчиком программного
обеспечения с открытым исходным кодом из Свазиленда (Африка). Как утверждал Эм-
броуз, кличка Сакила своими корнями уходит в Си-Свати (SiSwati) - язык, на котором
говорят в Свазиленде. Сакила - это также название города в Аруше (Танзания), рядом с
родной страной Эмброуза, Угандой.
20 Глава 1. Общая информация

1.2.2. Основные возможности MySQL


Ниже представлен список наиболее важных характеристик программного обеспече-
ния баз данных MySQL. Дополнительную информацию о текущих и планируемых воз-
можностях можно получить в разделе 1.5.
• Внутренние характеристики и переносимость.
• Написан на языках С и C++.
• Протестирован на широком спектре различных компиляторов.
• Работает на множестве различных платформ.
• Для обеспечения переносимости использует инструменты GNU - Automake,
Autoconf и Libtool.
• Доступны API-интерфейсы для С, C++, Eiffel, Java, Perl, PHP, Python, Ruby и Tel.
• Полностью многопоточный с использованием потоков ядра. Может работать в
многопроцессорных системах.
• Обеспечивает транзакционный и нетранзакционный механизмы хранения.
• Использует очень быстрые дисковые таблицы (MylSAM) со сжатием индексов
на основе бинарных деревьев (В-деревьев).
• Сравнительно простое добавление другого механизма хранения. Это удобно, ес-
ли требуется добавить SQL-интерфейс к базе данных собственной разработки.
• Очень быстрая система распределения памяти, основанная на потоках.
• Очень быстрые соединения, использующие оптимизированные однопроход-
ные мультисоединения.
• Хранимые в памяти хеш-таблицы, которые используются в качестве времен-
ных таблиц.
• Функции SQL реализованы с использованием высоко оптимизированной биб-
лиотеки классов и должны выполняться предельно быстро. Как правило, како-
го-либо распределения памяти после инициализации запроса не выполняется.
• Код MySQL протестирован с помощью инструментов поиска утечки памяти,
как коммерческих, так и с открытым исходным кодом.
• Сервер доступен как отдельная программа для использования в клиент-
серверной сетевой среде. Кроме того, он также поставляется в виде библиоте-
ки, которая может быть встроена в отдельные автономные приложения. Такие
приложения могут применяться в изолированной среде или среде, не имеющей
доступа к сети.
• Типы столбцов
• Множество типов данных для столбцов таблиц: знаковые/беззнаковые целые
ДЛИНОЙ В 1, 2, 3, 4 И 8 байт; ТИПЫ FLOAT, DOUBLE, CHAR, VARCHAR, TEXT, BLOB, DATE,
TIME, DATETIME, TIMESTAMP, YEAR, SET, ENUM и пространственные типы OpenGIS.
• Записи фиксированной и переменной длины.
• Операторы и функции.
• Полная поддержка операций и функций в конструкциях SELECT и WHERE запро-
сов, например:
1.2. Что такое система управления базами данных MySQL 21

raysql> SELECT CONCAT(first_name, ' ' , lastjiame)


-> FROM c i t i z e n
-> WHERE income/dependents > 10000 AND age > 30;
• Полная поддержка конструкций GROUP BY и ORDER BY. Поддержка групповых
функций (COUNT (), COUNT (DISTINCT . . . ) , AVG(), STD(), SUM(), MAX(), MIN() И
GROUP_CONCAT()).
• Поддержка LEFT OUTER JOIN и RIGHT OUTER JOIN как с синтаксисом SQL, так и
с синтаксисом ODBC.
• Поддержка псевдонимов для таблиц и столбцов, как того требует стандарт
SQL.
• Операторы DELETE, INSERT, REPLACE и UPDATE возвращают количество строк,
которые были изменены. Вместо этого можно задать возврат количества строк,
соответствующих запросу, для чего потребуется установить соответствующий
флаг при подключении к серверу.
• Специфическая для MySQL команда SHOW может быть использована для
извлечения информации о базах данных, таблицах и индексах. Команда
EXPLAIN позволяет просмотреть, как оптимизатор выполняет запрос.
• Имена функций не конфликтуют с именами таблиц и столбцов. Например,
ABS - абсолютно корректное имя столбца. Единственное ограничение, которое
накладывается на вызов функций, - это то, что между именем функции и сле-
дующей за ним открывающей скобкой ' (' не должно быть пробелов.
• Можно смешивать таблицы из разных баз данных в одном запросе (как в
MySQL 3.22).
• Безопасность.
• Система, основанная на паролях и привилегиях, является исключительно гиб-
кой и безопасной и позволяет организовать верификацию средствами хоста.
Пароли защищены, поскольку весь трафик паролей во время соединения с сер-
вером шифруется.
• Масштабируемость и ограничения.
• Поддерживает работу баз данных огромных объемов. Например, компания
MySQL AB применяет сервер MySQL для обслуживания базы данных, содер-
жащей 50 миллионов записей. Известна также организация, использующая
сервер MySQL для обслуживания базы данных из 60 000 таблиц, которая хра-
нит около 5 миллиардов записей.
• Разрешается иметь до 64 индексов на таблицу (в версиях, предшествующих
MySQL 4.1.2, допускалось до 32 индексов). Каждый индекс может содержать от
1 до 16 столбцов или частей столбцов. Максимальная ширина индекса составля-
ет 1000 байт (500 байт в версиях, предшествующих MySQL 4.1.2). Для индекса
может применяться префикс столбцов с типами CHAR, VARCHAR, BLOB и TEXT.
• Сетевая связность
• Клиенты могут подключаться к серверу MySQL, используя сокеты TCP/IP на
любой платформе. В Windows-системах семейства NT (NT, 2000 или ХР) клиен-
ты могут подключаться с использованием именованных каналов. В системах на
базе UNIX клиенты могут подключаться через файлы сокетов UNIX-доменов.
22 Глава 1. Общая информация

• Интерфейс Connector/ODBC позволяет MySQL поддерживать клиентские про-


граммы, которые используют ODBC-соединения. Например, для подключения
к серверу MySQL можно использовать MS Access. Клиентское программное
обеспечение может выполняться под управлением Windows или UNIX. Исход-
ные тексты интерфейса Connector/ODBC доступны. Поддерживаются все
функции ODBC 2.5, равно как и множество других.
• Интерфейс Connector/JDBC позволяет MySQL взаимодействовать с клиент-
скими программами на Java, в которых используются JDBC-подключения.
Клиентское программное обеспечение может выполняться под управлением
Windows или UNIX. Исходные тексты интерфейса Connector/JDBC доступны.
• Локализация
• Сервер может выдавать клиентам сообщения об ошибках на разных языках.
• Полностью поддерживаются несколько кодовых таблиц, включая l a t i n l (ISO-
8859-1), german, big5, ujis и другие. Например, в именах таблиц и столбцов
разрешается применять скандинавские символы наподобие 'а', 'а' и 'б'. Начи-
ная с версии MySQL 4.1, также обеспечивается поддержка Unicode.
• Все данные сохраняются в выбранной кодировке. Все сравнения столбцов с
нормальными строками чувствительны к регистру.
• Сортировка выполняется в соответствии с выбранной кодировкой (по умолча-
нию используется шведский набор). Во время запуска сервера MySQL это
можно изменить. В качестве примера весьма совершенной сортировки реко-
мендуется обратить внимание на код сортировки для чешского языка. Сервер
MySQL поддерживает множество различных кодировок, причем они могут
быть указаны как во время компиляции, так и во время выполнения.
• Клиенты и инструменты.
• Сервер MySQL имеет встроенную поддержку SQL-операторов для проверки,
оптимизации и восстановления таблиц. Эти операторы можно выполнять в
режиме командной строки, используя клиентское приложение mysqlcheck.
MySQL включает также myisamchk - очень быструю утилиту командной стро-
ки для реализации тех же операций над таблицами MylSAM.
• Все программы MySQL можно запускать на выполнение с опцией —help или
-? для получения быстрой подсказки.

1.2.3. Стабильность MySQL


Этот раздел отвечает на вопросы "Насколько стабилен сервер MySQL?" и "Можно ли
положиться на MySQL в этом проекте?". Мы попытаемся прояснить это, а также отве-
тить на некоторые важные вопросы, которые касаются множества потенциальных поль-
зователей. Информация, представленная в этом разделе, основана на данных, собранных
из списков рассылки и писем пользователей, которые проявляют завидную активность
при обсуждении проблем и способов их решения.
Основной программный код был разработан в начале восьмидесятых годов прошлого
века. Он обеспечил стабильную базу и поддерживал формат таблиц ISAM, используе-
мый оригинальным механизмом хранения, который остается обратно совместимым и по
сей день. В ТсХ, компании-предшественнице MySQL AB, код MySQL без проблем рабо-
тал в проектах, начиная со средины 1996 года. Когда программное обеспечение MySQL
1.2. Что такое система управления базами данных MySQL 23

впервые было представлено широкой публике, пользователи быстро нашли фрагменты,


которые не был протестированы. Каждая новая реализация с тех пор имела все меньше и
меньше проблем переносимости, несмотря на то, что в каждой из них также добавлялось
множество новых возможностей.
Каждый выпуск сервера MySQL была работоспособным. Проблемы возникали толь-
ко тогда, когда пользователи имели дело с кодом из так называемых "серых зон". Есте-
ственно, новые пользователи не знают, что это за зоны, поэтому в настоящем разделе мы
попытаемся документировать те из них, которые известны в настоящий момент. Это
описание в большей степени касается версий MySQL 3.23 и MySQL 4.O. Все известные и
документированные ошибки в последней версии были исправлены, за исключением тех,
что перечислены в разделе ошибок, имеющих отношение к собственно проекту (см. раз-
дел 1.8.7).
Проект MySQL построен по многоуровневому принципу с независимыми модулями.
Некоторые из новейших модулей перечислены ниже с указанием того, насколько хоро-
шо они были протестированы.
• Репликация (гамма-версия).
Большая группа серверов, использующих репликацию, показали хорошие резуль-
таты во время производственной эксплуатации. В MySQL 5.x продолжается рабо-
та над расширенными средствами репликации.
• Таблицы innoDB (стабильная версия).
Транзакционный механизм хранения был объявлен стабильным в дереве выпус-
ков MySQL 3.23, начиная с 3.23.49. Таблицы InnoDB используются в больших,
сильно загруженных производственных системах.
• Таблицы BDB (гамма-версия).
Код Berkley DB очень стабилен, однако совершенствование интерфейса транзак-
ционного механизма хранения BDB в сервере MySQL продолжается, поэтому еще
пройдет некоторое время, прежде чем модуль обслуживания таблиц BDB можно
будет объявить настолько же тщательно протестированным, как и соответствую-
щие модули для других типов таблиц.
• Полнотекстовый поиск (гамма-версия).
Полнотекстовый поиск работает, но пока широко не используется. В версию
MySQL 4.0 были внесены важные усовершенствования.
• Connector/ODBC 3.51 (стабильная версия).
Connector /ODBC 3.51 использует комплект ODBC SDK 3.51 и широко применяется
в производственных системах. Некоторые его выпуски зависимы от приложений
и не зависят от ODBC-драйвера или лежащего в основе сервера баз данных.
• Автоматическое восстановление таблиц My ISAM (гамма-версия).
Состояние "гамма" касается только нового кода в механизме хранения My ISAM, ко-
торый при открытии таблиц проверяет, были ли они правильно закрыты и, если
нет, выполняет автоматическую проверку и восстанавливает их.

1.2.4. Размеры таблиц MySQL


В MySQL 3.22 существовало ограничение в 4 Гбайт на размер таблиц. С применени-
ем механизма хранения MylSAM в MySQL 3.23 предельный размер таблиц вырос до 8
24 Глава 1. Общая информация

миллионов Тбайт (2 6 3 байт). На практике это означает, что максимальные размеры таб-
лиц теперь определяются ограничениями, накладываемыми операционной системой на
размеры файлов, а не внутренними ограничениями MySQL.
Механизм хранения таблиц InnoDB поддерживает таблицы InnoDB внутри таблич-
ных пространств, которые могут состоять из нескольких файлов. Это позволяет таблице
превысить максимальный размер отдельного файла. Табличное пространство может
включать неразмеченные дисковые разделы (находящиеся вне файловой системы ОС),
что позволяет иметь чрезвычайно большие таблицы. Максимальный размер табличного
пространства составляет 64 терабайта.
В табл. 1.1 приведены некоторые примеры ограничений на размеры файлов, налагае-
мые операционными системами.
Таблица 1.1. Ограничения на размеры файлов со стороны операционных систем
Операционная система Ограничение размера файла
Linux-Intel, 32-разрядная 2 Гбайт, при использовании файловой системы LFS
значительно больше
Linux-Alpha 8 Тбайт (?)
Solaris 2.5.1 2 Гбайт (4 Гбайт с обновлениями)
Solaris 2.6 4 Гбайт (может быть изменено с помощью флагов)
Solaris 2.7 Intel 4 Гбайт
Solaris 2.7 UltraSPARC 512 Гбайт
NetWare с файловой системой NSS 8 Тбайт

В Linux 2.2 можно иметь таблицы My ISAM размером свыше 2 Гбайт, если воспользо-
ваться обновлением LFS (Large Files Support - поддержка больших файлов) для файло-
вой системы ext2. В Linux 2.4 существуют также обновления поддержки больших фай-
лов для файловой системы ReiserFS. Большинство современных дистрибутивов Linux
базируются на ядре 2.4 и уже оснащены всеми необходимыми обновлениями LFS. Одна-
ко максимально доступный размер файлов по-прежнему зависит от ряда факторов, один
из которых - это тип файловой системы, используемой для хранения таблиц MySQL.
Детальный обзор LFS для Linux можно найти на странице Андреаса Джаегера
(Andreas Jaeger) "Large File Support in Linux" ("Поддержка больших файлов в Linux") no
адресу http://www.suse.de/~aj/linux_lfs.html.
По умолчанию MySQL создает таблицы My ISAM с внутренней структурой, разреша-
щей максимальный размер таблицы в 4 Гбайт. Максимальный размер таблицы можно
проверить с помощью команды SHOW TABLE STATUS или myisamchk -dv имя_таблицы.
Если необходимо работать с таблицами My ISAM размером свыше 4 Гбайт (и ваша опе-
рационная система поддерживает файлы упомянутого размера), на этот случай в опера-
торе CREATE TABLE предусмотрены опции AVG_ROW__LENGTH и MAX_R0WS. Эти опции также
можно изменить с помощью команды ALTER TABLE уже после создания таблицы, и таким
образом увеличить ее максимально допустимый размер.
Ниже представлены другие способы преодоления ограничений на размер таблиц
My ISAM, налагаемых операционной системой.
• Если большая таблица используется только для чтения, с помощью утилиты
myisampack ее можно сжать. Как правило, эта утилита сжимает таблицу примерно
1.2. Что такое система управления базами данных MySQL 25

до 50% от начального размера. В результате можно иметь дело со значительно


большими таблицами. Посредством утилиты myisampack можно также объединить
несколько таблиц в одну.
• Другой способ преодоления ограничений на размер файла операционной системы
для таблиц My ISAM заключается в использовании опции RAID.
• MySQL включает в себя библиотеку MERGE, которая позволяет управлять набором
таблиц My ISAM с идентичной структурой, как одной объединенной таблицей.

1.2.5. Решение "проблемы 2000 года91


В сервере MySQL известная "проблема 2000 года" (Y2K) полностью решена.
• В MySQL используются функции времени Unix, которые обрабатывают даты
вплоть до 2037 года как значения типа TIME STAMP. Для значений типа DATE и
DATETIME допустима работа с датами вплоть до 9999 года.
• Все функции времени MySQL хранятся в одном исходном файле - sql/time.cc;
они реализованы настолько тщательно, что являются безопасными в контексте
"проблемы 2000 года".
• В MySQL 3.22 и последующих версиях столбцы типа YEAR могут хранить год 0 и
значения лет от 1901 до 2155 в одном байте и отображать их в виде двузначного
или четырехзначного числа. Все двузначные годы рассматриваются как принад-
лежащие диапазону от 1970 до 2069; это означает, что если в столбце YEAR сохра-
няется значение 01, MySQL трактует его как 2001 год.
Приведенный далее код служит простой демонстрацией того, что сервер MySQL не
имеет проблем со значениями типов DATE и DATETIME вплоть до 9999 года, а со значе-
ниями типа TIMESTAMP - после 2030 года.
mysql> DROP TABLE IF EXISTS y2k;
Query OK, 0 rows a f f e c t e d ( 0 . 0 1 s e c )
(Запрос успешно выполнен, затронуто 0 строк (0.01 с))
mysql> CREATE TABLE y2k (date DATE,
-> date_time DATETIME,
-> time_stamp TIMESTAMP) ;
Query OK, 0 rows a f f e c t e d ( 0 . 0 1 s e c )
mysql> INSERT INTO y2k VALUES
-> ('1998-12-31','1998-12-31 23:59:59',19981231235959),
-> ('1999-01-01','1999-01-01 00:00:00',19990101000000),
-> ('1999-09-09','1999-09-09 23:59:59',19990909235959),
-> ('2000-01-01','2000-01-01 00:00:00',20000101000000),
-> ('2000-02-28','2000-02-28 00:00:00',20000228000000),
-> ('2000-02-29','2000-02-29 00:00:00',20000229000000),
-> ('2000-03-01','2000-03-01 00:00:00',20000301000000),
-> ('2000-12-31','2000-12-31 23:59:59',20001231235959),
-> ('2001-01-01','2001-01-01 00:00:00',20010101000000),
-> ('2004-12-31','2004-12-31 23:59:59',20041231235959),
-> ('2005-01-01','2005-01-01 00:00:00',20050101000000),
-> ('2030-01-01','2030-01-01 00:00:00',20300101000000),
-> ('2040-01-01','2040-01-01 00:00:00',20400101000000),
-> ('9999-12-31','9999-12-31 23:59:59',99991231235959);
26 Глава 1. Общая информация

Query OK, 14 rows a f f e c t e d (0.01 sec)


Records: 14 D u p l i c a t e s : 0 Warnings: 2
(Записей: 14 Дубликатов: 0 Предупреждений: 2)
mysql> SELECT * FROM y2k;

I date d a t e time time_stamp

1998- •12-31 1998- 12-31 23:59: 59 19981231235959


1999-•01-01 1999- 01-01 00:00: 00 19990101000000
1999-•09-09 1999- 09-09 23:59: 59 19990909235959
2000- •01-01 2000- 01-01 00:00: 00 20000101000000
2000- •02-28 2000- •02-28 00:00: 00 20000228000000
2000- •02-29 2000- 02-29 00:00: 00 20000229000000
2000- •03-01 2000- •03-01 00:00: 00 20000301000000
2000- •12-31 2000- •12-31 23:59: 59 20001231235959
2001-•01-01 2001- •01-01 00:00: 00 20010101000000
2004-•12-31 2004- •12-31 23:59: 59 20041231235959
2005-•01-01 2005- •01-01 00:00: 00 20050101000000
2030-•01-01 2030- •01-01 00:00: 00 20300101000000
2040-•01-01 2040- •01-01 00:00; 00 00000000000000
9999-•12-31 9999-•12-31 23:59: 59 00000000000000

14 rows in set (0.00 sec)


(14 записей в наборе (0.00 с))
Последние два значения столбца TIME_STAMP равны нулю, потому что последние два
значения года (2040 и 9999) выходят за пределы, допустимые для типа данных
TIMESTAMP. Этот тип данных, используемый для хранения текущего времени, поддержи-
вает значения (со знаком) в диапазоне от 19700101000000 до 20300101000000 на 32-
разрядных машинах. На 64-разрядных машинах тип TIMESTAMP допускает значения (без
знака) до 2106 года.
Несмотря на то что сервер MySQL сам по себе безопасен с точки зрения "проблемы
2000 года", неприятности могут быть вызваны приложениями, которые небезопасны в
этом плане. Например, многие старые приложения хранят и манипулируют датами, ис-
пользуя двузначную запись года вместо четырехзначной. Эта проблема может еще более
усугубиться приложениями, которые трактуют значения года 00 и 99 как индикатор "по-
терянных" или неопределенных значений. К сожалению, упомянутые проблемы зачас-
тую очень трудно исправить, поскольку различные приложения разработаны разными
программистами, каждый из которых может использовать собственный набор соглаше-
ний и функций обработки дат.
Таким образом, сам сервер MySQL защищен от "проблемы 2000 года", а ответствен-
ность за корректный ввод ложится на приложения.

1.3. Компания MySQL AB


MySQL AB - это компания основателей и основных разработчиков MySQL. Она бы-
ла основана в Швеции Дэвидом Аксмарком (David Axmark), Алланом Ларссоном (Allan
Larsson) и Майклом Монти Видениусом (Michael "Monty" Widenius).
Все разработчики сервера MySQL работают на компанию. MySQL AB - виртуальная
организация, объединяющая людей из нескольких десятков стран мира. Каждый день мы
1.3. Компания MySQL AB 27

интенсивно общаемся через Internet друг с другом, с нашими пользователями, сторонни-


ками и партнерами.
Мы посвятили себя разработке программного обеспечения баз данных MySQL и про-
движению его для новых пользователей. Компания MySQL AB владеет авторскими пра-
вами на исходные тексты MySQL, логотип и торговую марку MySQL, а также на данное
руководство (см. раздел 1.2).
Ключевые принципы MySQL показывают наше отношение к продукту и инициативе
программного обеспечения с открытым исходным кодом. Компания MySQL AB стре-
мится, чтобы программное обеспечение сервера MySQL соответствовало следующим
критериям:
• Лучший и наиболее широко используемый в мире.
• Доступный всем.
• Простой в эксплуатации.
• Постоянно совершенствующийся без влияния на производительность и защищен-
ность.
• Приносящий удовольствие от использования и улучшения.
• Свободный от ошибок.
Далее перечислены принципы, которыми руководствуется компания MySQL AB и ее
сотрудники.
• Мы поддерживаем философию открытого исходного кода, а также сообщество
пользователей программного обеспечения с открытым исходным кодом (Open
Source).
• Мы стремимся быть хорошими гражданами.
• Мы предпочитаем работать с партнерами, которые разделяют наши взгляды и
убеждения.
• Мы отвечаем на электронную почту и обеспечиваем поддержку пользователей.
• Мы - виртуальная компания, взаимодействующая через Internet.
• Мы - противники патентования программного обеспечения.
Web-сайт MySQL (http://www.mysql.com) предоставляет актуальную информацию
по MySQL и компании MySQL AB.
Кстати, часть "АВ" в имени компании означает шведское "aktiebolag" - "акционерная
компания". То есть MySQL AB в английском варианте может выглядеть как MySQL, Inc.
Фактически, MySQL, Inc. и MySQL GmbH являются представительствами MySQL AB,
расположенными, соответственно, в США и Германии.

1.3.1. Бизнес-модель и услуги, оказываемые MySQL AB


Один из наиболее часто задаваемых нам вопросов звучит так: "Как вы можете жить с
того, что предоставляете бесплатно?". А вот как:
• Компания MySQL AB зарабатывает деньги на поддержке, услугах, коммерческих
лицензиях и авторских отчислениях.
• Мы используем эти доходы для финансирования разработки и расширения бизне-
са, связанного с MySQL.
28 Глава 1. Общая информация

Компания была прибыльной, начиная со дня ее основания. В октябре 2001 года мы


получили финансирование от ведущих скандинавских инвесторов. Эти инвестиции ис-
пользовались для упрочнения нашей бизнес-модели и заложили фундамент устойчивого
роста.

1.3.1.1. Поддержка
Компанией MySQL AB владеют и управляют учредители и основные разработчики
СУБД MySQL. Наши разработчики взяли на себя обязательство осуществлять поддерж-
ку клиентов и других пользователей с тем, чтобы постоянно быть в курсе их нужд и
проблем. Вся поддержка выполняется только квалифицированным персоналом. На са-
мые каверзные вопросы отвечает сам Майкл Монти Видениус - автор и идеолог сервера
MySQL.
Коммерческие клиенты получают высококачественную поддержку непосредственно
от MySQL AB. Компания также поддерживает множество списков рассылки, в которых
любой может задать вопрос на интересующую его тему.
Более подробная информация о поддержке разного уровня содержится в разделе 1.4.

1.3.1.2. Обучение и сертификация


Компания MySQL AB распространяет продукт MySQL и проводит обучающие курсы
по нему во всем мире. Мы предлагаем как открытые курсы, так и курсы на территории
заказчика, в соответствии с нуждами вашей организации. Обучающие курсы по MySQL
проводят также наши партнеры - авторизованные обучающие центры.
В наших обучающих материалах используются те же примеры баз данных, что и в
документации и типовых приложениях, поставляемых вместе с продуктом. Эти мате-
риалы постоянно обновляются, чтобы соответствовать самой последней версии MySQL.
Наши инструкторы постоянно взаимодействуют с группой разработчиков, что гаранти-
рует качество обучения и постоянное совершенствование учебного материала.
Посещение наших обучающих курсов позволит быстрее достичь целей, которые ста-
вятся при разработке MySQL-приложений. Кроме того, существуют и другие преимуще-
ства:
• Экономия времени.
• Повышение производительности приложений.
• Повышение степени защищенности приложений.
• Более полное удовлетворение потребностей заказчиков и сотрудников.
• Подготовка к сертификации по MySQL.
Если вы заинтересовались нашими обучающими курсами как потенциальный
клиент или партнер, посетите соответствующий раздел на нашем сайте по адресу
http://www.mysql.com/training/ либо свяжитесь с нами по электронной почте:
[email protected].
Подробная информация, касающаяся программы сертификации, доступна по адресу
http://www.mysql.com/certification/.

1.3.1.3. Консультации
Компания MySQL AB и ее авторизованные партнеры предоставляют консалтинговые
услуги пользователям сервера MySQL и тем, кто встраивает сервер MySQL в собствен-
ные приложения, по всему миру.
1.3. Компания MySQL AB 29

Наши консультанты окажут квалифицированную помощь в проектировании и на-


стройке баз данных, разработке эффективных запросов, настройке платформ для дости-
жения оптимальной производительности, решении вопросов миграции, репликации, по-
строении устойчивых транзакционных приложений и многом другом.
Консультанты тесно сотрудничают с группой разработки, что обеспечивает высокое
качество их профессиональных услуг. Период проведения консультаций может состав-
лять от двух дней интенсивных сеансов до временных промежутков, исчисляемых не-
сколькими неделями и месяцами. Консультации охватывают круг вопросов, связанных
не только непосредственно с MySQL, но также и с языками программирования и напи-
сания сценариев, такими как Perl, PHP и так далее.
Все, кто заинтересован в услугах наших консультантов или же в партнерстве в
этой области, могут посетить соответствующий раздел нашего сайта по адресу
http://www.mysql.com/consulting/ либо связаться с нами по электронной почте:
[email protected].

1.3.1.4. Коммерческие лицензии


СУБД MySQL распространяется на условиях общедоступной лицензии GNU (General
Public License - GPL). Это означает, что в соответствии с GPL программное обеспечение
MySQL может использоваться бесплатно. Если вы не согласны с требованиями GPL (та-
кими, например, как то, что ваши приложения также должны распространяться на усло-
виях лицензии GPL), можете приобрести коммерческую лицензию на этот же продукт у
компании MySQL AB (https://order.mysql.com/). Поскольку права на исходный код
MySQL принадлежат MySQL AB, у нас есть возможность применять практику двойного
лицензирования, в соответствие с которым один и тот же продукт распространяется как
на условиях GPL, так и по коммерческой лицензии. Это совершенно не означает, что
компания MySQL AB отступает от принципов открытого исходного кода. Подробная
информация о том, в каких случаях необходима коммерческая лицензия, содержится в
разделе 1.4.3.
Компания MySQL AB также продает коммерческие лицензии на продукты Open
Source GPL независимых разработчиков, которые привносят некоторую новую функ-
циональность в сервер MySQL. Хорошим примером может служить транзакционный
механизм хранения innoDB, который предназначен для поддержки ACID, блокировок на
уровне строк, восстановления после аварий, управления версиями, внешних ключей и
так далее.

1.3.1.5. Партнерство
Компания MySQL AB поддерживает глобальную партнерскую программу, вклю-
чающую обучающие курсы, консультирование и поддержку, публикации, продажу и
распространение MySQL и связанных с ним продуктов. Партнеры MySQL AB указаны
на нашем Web-сайте по адресу http://www.mysql.com/. Там же имеется информация о
правах на использование специальных версий торговых марок MySQL для идентифика-
ции партнерских продуктов и продвижения их на рынке.
Если вы заинтересованы в том, чтобы стать партнером MySQL AB, обращайтесь к
нам по адресу partner@mysql. com.
Слово "MySQL" и логотип с дельфином MySQL являются торговыми марками ком-
пании MySQL AB (см. раздел 1.4.4). Признание и узнаваемость этих торговых марок
говорят о значительном вкладе основателей MySQL в технологии СУБД с открытым
исходным кодом.
30 Глава 1. Общая информация

Web-сайт MySQL (http://www.mysql.com) весьма популярен среди разработчиков и


пользователей. В декабре 2003 года на нем было зарегистрировано около 16 миллионов
посещений. Люди, проявляющие интерес к этому сайту, в большинстве своем представ-
ляют группу лиц, принимающих решения и выдающих рекомендации по поводу приоб-
ретения программного и аппаратного обеспечения. Двенадцать процентов визитеров
уполномочены принимать такие решения, и только девять процентов не имеют отноше-
ния к этому процессу. Более 65% делали одну или более покупок за последние полгода и
70% планируют это в течение ближайших месяцев.

1.3.2. Контактная информация


Web-сайт MySQL (http://www.mysql.com) предоставляет самую последнюю инфор-
мацию о MySQL и компании MySQL AB.
Если вы нуждаетесь в какой-то информации, не раскрытой в нашем разделе новостей
(http://www.mysql.com/news-and-events/), присылайте запросы по электронной почте
на адрес press@mysql. com.
Если вы заключили договор о поддержке с компанией MySQL AB, вы получите свое-
временные исчерпывающие ответы на все технические вопросы относительно про-
граммного обеспечения MySQL. За подробной информацией обращайтесь в раздел 1.4.1,
на наш сайт в раздел http://www.mysql.com/support или присылайте электронные
письма по адресу sales@mysql. com.
Информацию, касающуюся обучающих курсов по MySQL, можно получить на сайте
http://www.mysql.com/training/ или по электронной почте, отправив запрос по адресу
[email protected]. Обратитесь также в раздел 1.3.1.2.
Информация о программе сертификации MySQL доступна по адресу
http://www.mysql.com/certification/. Обратитесь также в раздел 1.3.1.2.
Если вы заинтересованы в консультациях, посетите соответствующий раздел на на-
шем сайте по адресу http://www.mysql.com/consulting/ или присылайте запрос по
электронной почте: [email protected]. Обратитесь также в раздел 1.3.1.3.
Коммерческие лицензии можно приобрести через Internet по адресу
https: //order .mysql. com/. Там же вы найдете информацию о том, как отправить факс с
заказом в компанию MySQL AB. Дополнительная информация о лицензировании дос-
тупна по адресу http://www.mysql.com/products/pricing.html. Если у вас возникли
вопросы относительно лицензирования, заполните контактную форму на Web-сайте
http://www.mysql.com либо пришлите электронное письмо по адресу [email protected]
(по вопросам лицензирования) или по адресу [email protected] (по вопросам приобрете-
ния). Обратитесь также в раздел 1.4.3.
Если вы представляете компанию, заинтересованную в партнерских отношениях с
MySQL AB, присылайте электронные письма по адресу [email protected]. Обратитесь
также в раздел 1.3.1.5.
Более подробную информацию о политике торговой марки MySQL можно получить
по адресу http://www.mysql.com/company/trademark.html либо через электронную поч-
ту: [email protected]. Обратитесь также в раздел 1.4.4.
Если вы заинтересованы поработать на компанию MySQL AB, обращайтесь в соот-
ветствующий раздел на сайте (http://www.mysql.com/company/jobs/) или пишите по
адресу [email protected]. Не отправляйте свое резюме как вложение, а размещайте его в
виде простого текста в конце электронного сообщения.
1.4. Поддержка и лицензирование MySQL 31

Для подключения к дискуссиям с другими пользователями просмотрите перечень


наших списков рассылки. Обратитесь также в раздел 1.7.1.
Сообщения об ошибках, равно как и вопросы и комментарии, должны отправляться в
общий список рассылки MySQL (см. раздел 1.7.1). Если вы обнаружили существенные
ошибки в системе безопасности сервера MySQL, незамедлительно уведомьте об этом по
адресу [email protected] (см. раздел 1.7.1.3).
Если вы располагаете результатами тестирования, которые стоит опубликовать, при-
сылайте их по адресу benchmark@mysql. com.
Если у вас есть предложения по дополнениям и исправлениям настоящего руково-
дства, направляйте их группе документации (docs@mysql. com).
Вопросы и комментарии относительно Web-сайта MySQL (http://www.mysql.com)
присылайте по адресу webmaster@mysql. com.
Компания MySQL AB имеет собственную политику конфиденциальности, с которой
можно ознакомиться по адресу http://www.mysql.com/company/privacy.html. Вопросы
по этой теме можно задавать и по электронной почте: privacy@mysql. com.
По всем остальным вопросам обращайтесь по адресу inf o@mysql. com.

1.4. Поддержка и лицензирование MySQL


В этом разделе описаны соглашения по поддержке и лицензированию MySQL.

1.4.1. Поддержка, предоставляемая компанией MySQL AB


Техническая поддержка компанией MySQL AB означает предоставление индивиду-
альных ответов по поводу решения ваших уникальных проблем непосредственно от
специалистов, которые занимаются разработкой СУБД MySQL.
Компания MySQL AB старается обеспечить широкий и всеобъемлющий подход к
оказанию технической поддержки. Почти любая проблема, касающаяся MySQL, важна
для нас, если она важна для вас. Обычно нашим заказчикам необходима помощь в том,
чтобы заставить работать различные команды и утилиты, устранить узкие места в про-
изводительности, восстановить систему после аварии, разобраться с влиянием операци-
онной системы или сетевой среды на MySQL, настроить процедуры резервирования и
восстановления данных, применять API-интерфейсы и так далее. Наша поддержка каса-
ется только сервера MySQL и наших собственных утилит, но не продуктов независимых
разработчиков, которые взаимодействуют с сервером MySQL, хотя по возможности мы
и стараемся оказать помощь и в отношении их.
Детальная информация о различных типах поддержки доступна по адресу
http://www.mysql.com/support/. Там же можно затребовать и поддержку в онлайновом
режиме. Чтобы связаться с персоналом, который занимается продажами, обращайтесь по
адресу [email protected].
Техническая поддержка во многом похожа на страхование жизни. Вы можете счаст-
ливо жить без нее многие годы. Однако когда ваш час наступит, она становится крити-
чески важной, но тогда уже слишком поздно ее приобретать. Если вы эксплуатируете
сервер MySQL для обслуживания важных приложений и сталкиваетесь с внезапными
сложностями, самостоятельный поиск ответов может оказаться слишком накладным в
смысле времени. Вам понадобится немедленно связаться с самыми опытными специали-
стами по устранению проблем, которые работают на компанию MySQL AB.
32 Глава 1. Общая информация

1.4.2. Авторские права и лицензии на MySQL


Компания MySQL AB владеет авторскими правами на исходный текст MySQL, лого-
типы, торговые марки и настоящее руководство (см. раздел 1.3). Важно знать несколько
лицензионных соглашений относительно распространения MySQL:
1. Исходный код сервера MySQL, библиотеки mysqlclient, клиентских утилит, а
также GNU-библиотеки readline, подпадает под действие лицензии GNU General
Public License (http://fsf.org/licenses/). Файл COPYING в дистрибутиве MySQL
содержит текст этой лицензии.
2. Использование библиотеки GNU getopt регламентируется малой общедоступной
лицензией GNU Lesser General Public License (http://www.fsf.org/licenses/).
3. Некоторые части исходных текстов (в частности, библиотека regexp) защищены
авторскими правами стиля Berkley.
4. Версии MySQL, предшествующие MySQL 3.22, регламентируются более строги-
ми лицензиями (http://www.mysql.com/products/mypl.html). Детальную инфор-
мацию можно найти в документации по этим версиям.
5. Распространение справочного руководства по MySQL не подпадает под действие
лицензии GPL. Использование этого руководства ограничено следующими усло-
виями:
• Допускается преобразование в старые форматы файлов, но текущее содержи-
мое документа не может быть изменено или отредактировано каким-либо об-
разом.
• Разрешена подготовка печатных копий для личного использования.
• Для любых других целей, таких как продажа печатных копий либо использо-
вание руководства или его частей в других публикациях, необходимо пись-
менное согласие компании MySQL AB.
• За дополнительной информацией или при возникновении желания принять
участие в переводе документации присылайте предложения по адресу
[email protected].
Сведения о действии лицензий MySQL на практике представлены в разделах 1.4.3
и 1.4.4 настоящего руководства.

1.4.3. Лицензии на MySQL


Программное обеспечение MySQL распространяется на условиях лицензии GNU General
Public License (GPL), которая является, вероятно, наилучшей лицензией для систем с
открытым исходным кодом. Формальные условия лицензии GPL доступны по адресу
http://www.fsf.org/licenses/. Имеет смысл также просмотреть информацию по адресам
http://www.fsf.org/licenses/gplfaq.html и http://www.gnu.org/philosophy/enforcing-
gpl.html.
Наша лицензия GPL предполагает ряд необязательных исключений, которые позво-
ляют многим приложениям, распространяемым на условиях Free/Libre and Open Source
("FLOSS"), включать в себя клиентские библиотеки MySQL, несмотря на тот факт, что
не все лицензии FLOSS совместимы с GPL. Более подробную информацию по этому
поводу можно найти на странице:
http://www.mysql.com/products/licensing/foss-exception.html
1.4. Поддержка и лицензирование MySQL 33

Поскольку программное обеспечение MySQL распространяется на условиях GPL,


оно зачастую может использоваться бесплатно, однако для некоторых целей требу-
ется коммерческая лицензия MySQL AB. Приобрести упомянутую лицензию можно
по адресу https://order.mysql.com/. Просмотрите также информацию по адресу
http://www.mysql.com/products/licensing.html.
Версии MySQL, предшествующие MySQL 3.22, подпадают под действие более стро-
гих лицензий (http://www.mysql.com/products/mypl.html). Дополнительная информа-
ция доступна в документации по MySQL соответствующих версий.
Обратите внимание на то, что использование программного обеспечения MySQL по
коммерческой лицензии, GPL либо по старой лицензии MySQL не предоставляет автомати-
чески права на использование торговой марки компании MySQL AB (см. раздел 1.4.4).

1.4.3.1. Использование программного обеспечения MySQL


по коммерческой лицензии
Лицензию GPL можно назвать "заразной" в том смысле, что когда программа связы-
вается с GPL-программой, все исходные тексты всех частей результирующего продукта
также подпадают под действие лицензии GPL. Если это требование не выполняется, тем
самым нарушаются условия лицензии, а право на использование GPL-программы утра-
чивается. В этом случае вы рискуете тем, что от вас могут потребовать материальной
компенсации за нарушение условий лицензии.
Коммерческая лицензия необходима в перечисленных ниже случаях.
• Если вы компонуете свою программу с любым кодом из состава программного
обеспечения MySQL, который подпадает под действие лицензии GPL, и не хоти-
те, чтобы результирующий продукт лицензировался на условиях GPL. Возможно,
это необходимо из-за того, что вы разрабатываете коммерческий продукт либо по
другим причинам желаете сохранить добавляемый вами код закрытым. Приобре-
тая коммерческую лицензию, вы используете то же самое программное обеспече-
ние MySQL, но только не в соответствие с лицензией GPL.
• Если вы распространяете приложение, использование которого не регламентиру-
ется лицензией GPL, но которое работает только с программным обеспечением
MySQL, и поставляете это приложение вместе с программным обеспечением
MySQL. Этот вариант решения рассматривается как компоновка, даже если части
результирующего продукта взаимодействуют только через сеть.
• Если вы распространяете копии программного обеспечения MySQL без поставки
исходного кода, как того требует лицензия GPL.
• Если вы хотите содействовать дальнейшей разработке СУБД MySQL, даже когда
коммерческая лицензия формально не нужна. Оплата услуг по поддержке непо-
средственно компании MySQL AB - еще один хороший способ содействия разра-
ботке программного обеспечения MySQL, причем с непосредственной выгодой
для вас (см. раздел 1.4.1).
Наша лицензия GPL предполагает ряд необязательных исключений, которые позво-
ляют многим приложениям, распространяемым на условиях Free/Libre and Open Source
("FLOSS"), включать в себя клиентские библиотеки MySQL, несмотря на тот факт, что
не все лицензии FLOSS совместимы с GPL. Более подробную информацию по этому
поводу можно найти на странице:
http://www.mysql.com/products/licensing/foss-exception.html
34 Глава 1. Общая информация

Если вы решили отдать предпочтение коммерческой лицензии, вам понадобится от-


дельная лицензия на каждую инсталляцию MySQL. Ее действие распространяется на
системы с любым количеством процессоров и с любым числом клиентов, которые под-
ключаются к серверу, причем любым способом.
Для приобретения коммерческих лицензий посетите наш Web-сайт по адресу
http://www.mysql.com/products/licensing.html. Чтобы заключить договор поддержки,
обращайтесь по адресу http://www.mysql.com/support/. Если имеются какие-то специ-
фические требования, свяжитесь с нашим персоналом, который занимается продажами,
по электронной почте: sales@mysql. com.

1.4.3.1. Бесплатное использование программного обеспечения MySQL


по лицензии GPL
Бесплатное использование программного обеспечения MySQL по лицензии GPL до-
пускается при условии выполнения требований GPL. Дополнительная информация о
GPL, в том числе ответы на часто задаваемые вопросы, доступна в разделе FAQ фонда
бесплатного программного обеспечения (Free Software Foundation) по адресу
http://www.fsf.org/licenses/gpl-faq.html.
Наша лицензия GPL предусматривает ряд необязательных исключений, которые по-
зволяют многим приложениям, распространяемым на условиях Free/Libre and Open
Source ("FLOSS"), включать в себя клиентские библиотеки MySQL, несмотря на тот
факт, что не все лицензии FLOSS совместимы с GPL. Более подробно об этом см.
http://www.mysql.com/products/licensing/foss-exception.html.
Ниже перечислены общие примеры использования GPL.
• Когда вы распространяете собственное приложение вместе с исходными текстами
и исходным кодом MySQL на условиях GPL.
• Когда вы распространяете исходный код MySQL в связке с другими программа-
ми, которые не компонуются и функционально не зависят от MySQL, даже если
эти программы распространяются на коммерческой основе. В лицензии GPL это
называется "чистой агрегацией" ("mere aggregation").
• Когда вы не распространяете никаких частей системы MySQL, вы можете ее ис-
пользовать бесплатно.
• Если вы являетесь поставщиком Internet-услуг, предоставляя своим клиентам
Web-хостинг и доступ к серверу MySQL. Мы рекомендуем сотрудничать с по-
ставщиками, у которых заключен договор поддержки MySQL, поскольку это дает
уверенность в том, что поставщик располагает всеми ресурсами для решения лю-
бых возникающих проблем с MySQL. Даже если поставщик Internet-услуг не име-
ет коммерческой лицензии на сервер MySQL, его клиенты, как минимум, должны
иметь доступ по чтению к исходным кодам инсталляции MySQL, дабы они могли
убедиться, что выполнены все изменения и исправления.
• Когда вы используете программное обеспечение баз данных MySQL в комплекте
с Web-сервером, вы не нуждаетесь в коммерческой лицензии (до тех пор, пока не
это является распространяемым вами продуктом). Это верно даже в том случае,
если функционирующий Web-сервер является коммерческим, и он использует
сервер MySQL, поскольку распространение частей системы MySQL не осуществ-
ляется. Однако в этом случае рекомендуется заключить договор поддержки
MySQL, так как программное обеспечение MySQL оказывает влияние на успеш-
ность вашего предприятия.
1.4. Поддержка и лицензирование MySQL 35

Если вы используете программное обеспечение баз данных MySQL и не нуждаетесь


в коммерческой лицензии, мы все равно рекомендуем вам заключить договор поддержки
с компанией MySQL AB. Это способ содействия дальнейшему развитию MySQL и одно-
временно получения непосредственной выгоды для вас (см. раздел 1.4.1).
Если программное обеспечение баз данных MySQL применяется в коммерческих це-
лях и от этого появляется некоторая прибыль, компания MySQL AB предлагает поддер-
жать дальнейшее развитие MySQL за счет заключения договора на поддержку опреде-
ленного уровня. Мы полагаем, что если СУБД MySQL помогает вашему бизнесу, то
логично попросить вас о содействии компании MySQL AB. (В противном случае полу-
чается, что задавая вопросы, касающиеся поддержки, вы не только бесплатно пользуе-
тесь тем, во что вложена немалая работа, но и просите предоставить бесплатную под-
держку.)

1.4.4. Логотипы и торговые марки MySQL AB


Многие пользователи СУБД MySQL желают размещать логотип с дельфином
MySQL AB на своих Web-сайтах, в книгах или на коробках с программными продукта-
ми. Мы приветствуем и поддерживаем это стремление, только при условии упоминания,
что слово "MySQL" и логотип дельфина являются торговыми марками MySQL AB и
могут использовать только так, как того требует наша политика относительно торговых
марок (см. http://www.mysql.com/company/trademark.html).

1.4.4.1. Оригинальный логотип MySQL


Логотип MySQL с изображением дельфина был разработан финским рекламным
агентством Priority в 2001 году. Дельфин был признан подходящим символом для СУБД
MySQL - столь же умное, быстрое, подвижное и свободно ориентирующееся в безбреж-
ном океане данных существо.
Оригинальный логотип MySQL может использоваться только как символ компании
MySQL AB и только теми, кто имеет соответствующее письменное разрешение.

1.4.4.2. Логотипы MySQL, которые можно использовать без письменного


разрешения
Мы разработали набор специальных условно используемых логотипов, которые мож-
но загрузить с нашего Web-сайта (http://www.mysql.com/press/logos.html) и исполь-
зовать на Web-сайтах независимых разработчиков без заключения письменных согла-
шений с компанией MySQL AB. Применение этих логотипов не является полностью
неограниченным, а регламентируется политикой относительно торговых марок, с кото-
рой можно ознакомиться на нашем сайте. Если вы планируете использовать их, внима-
тельно изучите все положения упомянутой политики. Ниже перечислены основные тре-
бования.
• Используйте требуемый логотип именно в том виде, в котором он представлен на
сайте http://www.mysql.com. Разрешено масштабировать его до нужных разме-
ров, однако нельзя изменять его цвета, дизайн, а также вносить любые другие из-
менения в этот графический образ.
• Явно укажите, что именно вы, а не компания MySQL AB являетесь создателем и
владельцем сайта, на котором представлено изображение торговой марки MySQL.
36 Глава 1. Общая информация

• Не допускается использовать торговую марку способом, приносящим ущерб ком-


пании MySQL AB или ее торговым маркам. Мы оставляем за собой право отби-
рать права на использование торговых марок MySQL AB.
• При размещении изображения торговой марки на Web-сайте, предусмотрите
ссылку, ведущую непосредственно на сайт h t t p : //www.mysql. com.
• Если вы используете СУБД MySQL на условиях лицензии GPL в приложении, это
приложение должно быть с открытым исходным кодом и должно иметь возмож-
ность подключаться к серверу MySQL.
В случае если вас интересуют какие-то специальные условия, которые соответствуют
вашим нуждам, свяжитесь с нами по электронной почте: trademark@mysql. com.

1.4.4.3. Когда необходимо иметь письменное разрешение


на использование логотипов MySQL
Письменное разрешение MySQL AB на использование логотипов MySQL необходи-
мо получать в следующих случаях:
• При использовании логотипов MySQL AB в любом другом месте, отличном от
Web-сайта.
• При использовании логотипа MySQL AB, не входящего в набор специальных ус-
ловно используемых логотипов (о которых упоминалось выше) на Web-сайте или
где-то еще.
На основе юридических и коммерческих соображений мы следим за использованием
торговой марки MySQL в продуктах, книгах и других местах. Обычно мы требуем плату
за изображение логотипа MySQL в коммерческих продуктах, поскольку считаем спра-
ведливым, чтобы некоторая часть дохода возвращалась нам для обеспечения дальнейше-
го развития СУБД MySQL.

1.4.4.4. Партнерские логотипы MySQL AB


Логотип партнера MySQL AB может использоваться только компанией, заключив-
шей письменное соглашение о партнерстве с MySQL AB. Партнерские отношения пре-
дусматривают сертификацию кого-либо в качестве инструктора или консультанта по
MySQL. Подробную информацию можно найти в разделе 1.3.1.5.

1.4.4.5. Использование слова "MySQL" в печатном тексте и презентациях


Компания MySQL AB приветствует ссылки на СУБД MySQL, однако при условии
упоминания о том, что слово "MySQL" является торговой маркой MySQL AB. По этой
причине к первому или наиболее заметному упоминанию слова "MySQL" в тексте дол-
жен быть добавлен значок торговой марки (®), а там, где это уместно, должно быть ука-
зано, что MySQL представляет собой торговую марку компании MySQL AB. За более
подробной информацией о нашей политике относительно торговых марок обращайтесь
по адресу http://www.mysql.com/corapany/trademark.html.

1.4.4.6. Использование слова "MySQL" в названиях компаний и продуктов


Использование слова "MySQL" в названиях компаний, продуктов или доменных
именах Internet без письменного разрешения компании MySQL AB не допускается.
1.5. План разработки MySQL 37

1.5. План разработки MySQL


В этом разделе в общих чертах представлен план разработки MySQL, включая ос-
новные средства, реализованные или планируемые для MySQL версий 4.0, 4.1, 5.0 и 5.1.
Последующие разделы дают информацию о каждой серии выпусков.
Серия производственных выпусков на момент написания этой книги - это MySQL
4.0, которая была представлена как устойчивая версия 4.0.12, ориентированная на про-
изводственное применение (выпущена в марте 2003 года). Это означает, что дальнейшие
разработки в рамках линейки 4.0 будут сводится только к исправлению ошибок. В ста-
рой серии MySQL 3.23 будут исправляться только критические ошибки.
Активная разработка MySQL сейчас сосредоточена на сериях MySQL 4.1 и MySQL
5.0. Это означает, что новые возможности будут добавляться только к MySQL 4.1 и
MySQL 5.0. На момент написания книги MySQL 4.1 доступен в виде бета-версии, а
MySQL 5.0 - в виде альфа-версии.
Ниже подытожены планы реализации наиболее востребованных возможностей.
Возможность Серия MySQL
Объединения 4.0
Подзапросы 4.1
R-деревья 4.1 (для таблиц My ISAM)
Хранимые процедуры 5.0
Представления 5.0
Курсоры 5.0
Внешние ключи 5.1 (уже реализованы в версии 3.23 для InnoDB)
Триггеры 5.1
Полные внешние соединения 5.1
Ограничения 5.1

1.5.1. Кратко о MySQL 4.0


Долгожданная версия MySQL 4.0 теперь доступна как производственный продукт. Ее
можно загрузить из сайта h t t p : //dev.mysql. com, а также с наших зеркальных сайтов.
Версия MySQL 4.0 была протестирована большим числом пользователей и эксплуа-
тируется на многих крупных Web-сайтах.
Основные возможности, вошедшие в состав сервера MySQL 4.0, были разработаны в
соответствии с текущими требованиями нашего бизнеса и потребностями сообщества
пользователей. Новые функции совершенствуют сервер баз данных MySQL как решение
для ответственных, сильно загруженных систем баз данных. Другие новые средства ори-
ентируются на пользователей встроенных баз данных.

1.5.1.1. Возможности, доступные в MySQL 4.0


• Повышение скорости работы.
• В версии MySQL 4.0 реализован кэш запросов, который обеспечивает сущест-
венный рост производительности для приложений, генерирующих повторяю-
щиеся запросы.
38 Глава 1. Общая информация

• В версии MySQL 4.0 еще более увеличилась скорость выполнения многих


операций, таких как пакетные операторы INSERT, поиск по упакованным ин-
дексам, полнотекстовый поиск (с использованием индексов FULLTEXT), а также
COUNT(DISTINCT).
• Новый встроенный сервер MySQL.
• С помощью новой библиотеки встроенного сервера можно легко создавать ав-
тономные и встроенные приложения. Встроенный сервер - это альтернатива
MySQL в клиент-серверной среде.
• Механизм хранения InnoDB в качестве стандарта.
• Механизм хранения InnoDB теперь позиционируется как стандартная функ-
циональная возможность сервера MySQL. Это означает полную поддержку
ACID-транзакций, внешних ключей с каскадными операторами INSERT и
DELETE, а также блокировок на уровне строки.
• Новая функциональность.
• Усовершенствованные поисковые свойства FULLTEXT в сервере MySQL 4.0 по-
зволяют индексировать большие объемы текстовой информации, как для логики
бинарного поиска, так и для поиска с применением естественного языка. Имеет-
ся возможность настройки минимальной длины слова и определения собствен-
ных списков недопустимых слов на любом естественном языке, что позволяет
разрабатывать новый набор приложений, использующих MySQL-сервер.
• Соответствие стандартам, переносимость и миграция
• Сервер MySQL теперь поддерживает оператор UNION - долгожданную воз-
можность стандартного языка SQL.
• MySQL теперь функционирует и на платформе Novell Netware, начиная с вер-
сии NetWare 6.O.
• Средства, упрощающие миграцию из других баз данных в среду сервера
MySQL, включая TRUNCATE TABLE (как у Oracle).
• Интернационализация
• Немецкие, австрийские и швейцарские пользователи обратят внимание, что
MySQL 4.0 поддерживает новый набор символов - l a t i n l d e , гарантирую-
щий, что порядок сортировки немецких символов расположит слова с умляу-
тами в порядке, принятом в немецких телефонных справочниках.
• Удобство использования
В процессе реализации новых средств для новых пользователей мы не забываем и
о запросах со стороны сообщества постоянных пользователей наших продуктов.
• Большинство параметров mysqld (опций запуска) теперь могут устанавливать-
ся без необходимости остановки сервера. Это удобное средство для админист-
раторов баз данных.
• Добавлены многотабличные операторы DELETE и UPDATE.
• В среде Windows управление символическими ссылками на уровне базы дан-
ных теперь по умолчанию включено. В среде UNIX механизм хранения My ISAM
теперь поддерживает символические ссылки на уровне таблиц (а не только на
уровне базы данных, как ранее).
1.5. План разработки MySQL 39

• Н о в ы е ф у н к ц и и SQL_CALC_FOUND_ROWS И FOUND_ROWS() ПОЗВОЛЯЮТ наЙТИ КОЛИ-


чество строк, которое должен вернуть оператор SELECT с конструкцией LIMIT,
как если бы этой конструкции не было.
В разделе новостей онлайнового руководства можно найти более детальный список
возможностей (см. http://dev.mysql.com/doc/mysql/en/News.html).

1.5.1.2. Встроенный сервер MySQL


Библиотека встроенного сервера libmysqld существенно расширяет сферу примене-
ния MySQL. Используя эту библиотеку, разработчики могут встраивать сервер MySQL в
различные приложения и электронные устройства, при этом конечные пользователи мо-
гут даже не подозревать о лежащей в основе СУБД. Встроенный сервер MySQL идеален
для использования в Internet-приложениях, общедоступных киосках, программно-
аппаратных устройствах, высокопроизводительных Internet-серверах, автономных базах
данных, распространяемых на компакт-дисках, и так далее.
Многие пользователи libmysqld получат несомненный выигрыш от двойного лицен-
зирования MySQL. Для тех, кто не желает быть связанным ограничениями лицензии
GPL, это программное обеспечение доступно по коммерческой лицензии. Библиотека
встроенного MySQL использует тот же интерфейс, что и обычная клиентская библиоте-
ка, поэтому она проста и удобна в эксплуатации.

1.5.2. Кратко о MySQL 4.1


Сервер MySQL версии 4.0 заложил основу для появления новых возможностей, таких
как подзапросы и поддержка Unicode, которые реализованы в версии 4.1, а также для
работы над хранимыми процедурами, которая завершается в версии 5.0. Упомянутые
возможности возглавляют список пожеланий большинства наших клиентов.
С появлением этих усовершенствований критикам MySQL понадобится проявить го-
раздо большее воображение, чтобы указать на недостатки в СУБД MySQL. Уже широко
зарекомендовавший себя как стабильный, быстрый и простой в эксплуатации, сервер
MySQL теперь готов к тому, чтобы удовлетворить требования самых взыскательных
потребителей.

1.5.2.1. Средства, доступные в MySQL 4.1


Все возможности MySQL 4.1, описанные в данном разделе, уже реализованы. Не-
сколько других средств MySQL 4.1 только планируются к реализации (см. раздел 1.6.1).
Набор возможностей, добавленных в версии 4.1, в основном утвержден. Большинст-
во новых средств, пребывающих в состоянии разработки, уже доступны или будут дос-
тупны в MySQL 5.0 (см. раздел 1.6.2).
MySQL 4.1 в настоящее время находится в стадии бета-тестирования, и его бинарные
файлы доступны для загрузки по адресу:
http://dev.mysql.com/downloads/mysql/4.1.html
Все бинарные реализации прошли интенсивное тестирование без каких-либо ошибок
на тех платформах, для которых они собраны.
Для тех, кто желает использовать наиболее актуальные исходные тексты, находя-
щиеся в процессе разработки, открыт доступ к нашему репозиторию BitKeeper для
MySQL 4.1.
40 Глава 1. Общая информация

MySQL 4.1 проходит стадию альфа-тестирования (в течение которой новые средст-


ва могут быть добавлены или изменены), стадию бета-тестирования (когда новая раз-
работка замораживается и выполняется только исправление ошибок) и стадию гамма-
тестирования (означающую, что производственный выпуск должен появиться в течение
нескольких недель). В конце этого процесса MySQL 4.1 становится новым производст-
венным выпуском.
• Поддержка подзапросов и порожденных таблиц.
• "Подзапрос" - это оператор SELECT, вложенный внутри другого оператора.
"Порожденная таблица" (неименованное представление) - это подзапрос в
конструкции FROM другого оператора.
• Увеличение скорости.
• Ускоренный бинарный клиент-серверный протокол с поддержкой предвари-
тельно подготовленных операторов и связывание параметров.
• Индексация BTREE теперь поддерживается для таблиц HEAP, значительно сни-
жая время реакции при нечетком поиске.
• Новая функциональность.
• Оператор CREATE TABLE имя_таблицы2 LIKE имя_таблицы1 позволяет с помо-
щью единственного оператора создавать новую таблицу со структурой, точно
такой же, как у существующей таблицы.
• Механизм хранения My ISAM теперь поддерживает пространственные типы
OpenGIS для хранения геометрических данных.
• Репликация может выполняться через SSL-соединения.
• Соответствие стандартам, переносимость и миграция
• Новый клиент-серверный протокол добавляет возможность передачи множе-
ственных предупреждений и сообщений клиенту вместо единственного ре-
зультата, как было раньше. Это упрощает процесс поиска причин проблем, ко-
торые могут возникнуть в таких операциях, как пакетная загрузка данных.
• SHOW WARNINGS показывает предупреждения, касающиеся последней выпол-
ненной команды.
• Интернационализация
• Для поддержки приложений, требующих использования национальных язы-
ков, программное обеспечение MySQL обеспечивает работу с кодировкой
Unicode через символьные наборы utf8nucs2.
• Символьные наборы теперь можно задавать для столбца, таблицы и базы дан-
ных. Это обеспечивает высокую степень гибкости при проектировании при-
ложений, в частности, многоязычных Web-сайтов.
• Удобство использования
• В ответ на многочисленные просьбы мы добавили команду HELP серверной
стороны, которая может предоставлять вспомогательную информацию об опе-
раторах SQL. Выгода от нахождения этой информации на стороне сервера за-
ключается в том, что клиенту всегда доступна справка по той версии сервера, к
которому он подключился. Поскольку эта информация доступна через опера-
тор SQL, любой клиент можно написать так, чтобы к ней был доступ. Напри-
1.6. MySQL и будущее (списки TODO) 41

мер, команда help в клиенте командной строки mysql была соответствующим


образом модифицирована.
• В новом клиент-серверном протоколе множественные операторы могут быть
отправлены одним вызовом.
• Новый клиент-серверный протокол также поддерживает возврат множества
результирующих наборов. Это может случиться, например, как результат
множественного запроса.
• Реализован новый синтаксис INSERT.. .ON DUPLICATE KEY UPDATE..., который
позволяет выполнять оператор UPDATE для существующей записи, если опера-
тор INSERT может привести к дублированию поля, служащего первичным клю-
чом или ключом уникального индекса.
• Введена новая агрегатная функция GROUP_CONCAT (), которая добавляет исклю-
чительно удобную возможность соединения значений столбцов из группиро-
ванных строк в единственную результирующую строку.
В разделе новостей онлайнового руководства можно найти более детальный список
возможностей (см. http://dev.mysql.com/doc/mysql/en/News.html).

1.5.3. MySQL 5.0: Очередной разрабатываемый выпуск


В настоящее время процесс разработки MySQL сфокусирован на выпуске 5.0, кото-
рый будет оснащен хранимыми процедурами и другими новыми возможностями (см.
раздел 1.6.2).
Для тех, кто желает взглянуть на передний край разработки MySQL, открыт публич-
ный доступ к репозиторию BitKeeper для MySQL 5.O. Начиная с декабря 2003 года, дос-
тупны также бинарные сборки версии 5.0.

1.6. MySQL и будущее (списки TODO)


В этом разделе описаны возможности, которые запланированы к реализации в серве-
ре MySQL. Позиции перечисляются по порядку номеров выпусков. Внутри списка пози-
ции следуют в том порядке, в котором, предположительно, они будут реализованы.
На заметку!
Если вы пользователь уровня предприятия, испытывающий срочную потребность в каком-то
конкретном средстве, свяжитесь с нашими специалистами по электронной почте
([email protected]), чтобы обсудить возможности спонсирования. Целевое финансирование
компаниями-спонсорами позволяет нам выделять дополнительные ресурсы для специфических
целей. Одним из примеров реализации такого сотрудничества, имевшего место в прошлом, яв-
ляется репликация.

1.6.1. Новые средства, запланированные для версии 4.1


Перечисленные ниже средства в MySQL 4.1 пока не реализованы, но планируются к
реализации до того момента, как MySQL 4.1 достигнет фазы бета-тестирования. Спи-
сок того, что уже реализовано в MySQL 4.1, представлен в разделе 1.5.2.1.
• Стабильная поддержка OpenSSL. (Поддержка SSL в MySQL 4.0 была в зачаточ-
ном состоянии и не на 100% протестирована.)
• Дополнительно протестирован механизм предварительно подготовленных опера-
торов.
42 Глава 1. Общая информация

• Дополнительно протестирована поддержка множественных символьных наборов


в одной таблице.

1.6.2. Новые средства, запланированные для версии 5.0


Перечисленные ниже средства планируются к включению в состав MySQL 5.O. Неко-
торые из них, например, хранимые процедуры, уже готовы и включены в выпуск MySQL
5.0 alpha, который уже доступен сейчас. Другие, такие как курсоры, готовы лишь час-
тично. Ожидается, что эти и некоторые другие средства будут поддерживаться в буду-
щих выпусках.
Следует отметить, что поскольку мы имеем дело с множеством разработчиков, кото-
рые заняты в разных проектах, то и количество дополнительных средств должно быть
значительным. Есть небольшая вероятность того, что часть из них войдут в выпуск
MySQL 4.1. Список того, что уже реализовано в MySQL 4.1, представлен в разделе 1.5.2.1.
Для тех, кто желает взглянуть на передний край разработки MySQL, открыт публич-
ный доступ к репозиторию BitKeeper для MySQL 5.0. Начиная с декабря 2003 года, дос-
тупны также бинарные сборки версии 5.0.
• Хранимые процедуры.
• Хранимые процедуры в настоящее время реализованы на базе стандарта
SQL:2003.
• Новая функциональность.
• Элементарная поддержка курсоров.
• Возможность явного указания для таблиц My ISAM, что индекс должен быть по-
строен как индекс RTREE (в MySQL 4.1 индексы RTREE используются внутренне
для геометрических данных GIS, но не могут быть созданы по запросу).
• Динамическая длина строк для таблиц MEMORY.
• Соответствие стандартам, переносимость и миграция
• Добавлена полноценная поддержка типа VARCHAR (ширина столбцов свыше 255
символов без усечения завершающих пробелов). В настоящее время существу-
ет поддержка этого в механизме хранения My ISAM, но пока это недоступно на
уровне пользователя.
• Увеличение скорости.
• Оператору SHOW COLUMNS FROM имя_таблицы (используется клиентом mysql для
того, чтобы позволить расширение имен столбцов) не требуется открывать
таблицу, а только файл определений. Это требует меньших затрат памяти и
получается значительно быстрее.
• Оператору DELETE на таблицах MylSAM теперь разрешено использовать кэш за-
писей. Чтобы обеспечить это, понадобилось обновлять кэш записей потоков
при обновлении файлов .MYD.
• Улучшенная поддержка таблиц MEMORY:
Динамическая длина строк.
Ускоренное управление строками (меньше копирования).
• Удобство использования
• Решение проблемы, возникающую при попытке выполнить RENAME TABLE для таб-
лиц, включенных в активные таблицы MERGE (возможно повреждение таблиц).
1.6. MySQL и будущее (списки TODO) 43

В разделе новостей онлайнового руководства можно найти более детальный список


возможностей (см. http: //dev.mysql. com/doc/mysql/en/News. html).

1.6.3. Новые средства, запланированные для версии5.1


• Новая функциональность.
• Поддержка внешних ключей (FOREIGN KEY) для всех типов таблиц, а не только
для InnoDB.
• Ограничения уровня столбца.
• Онлайновое резервное копирования с минимальным снижением производи-
тельности. Это позволит легко добавлять новые базы без необходимости оста-
навливать репликацию.
• Увеличение скорости.
• Новый формат файлов определения таблиц (. f rm) и табличный кэш для опре-
деления таблиц. Это позволит выполнять более быстрые запросы к структурам
таблиц и увеличить эффективность поддержки внешних ключей.
• Оптимизация типа BIT для хранения одного бита (в настоящее время тип BIT
хранится в байте и рассматривается как синоним TINYINT).
• Удобство использования.
• Добавление опций клиент-серверного протокола для получения информации о
процессе выполнения команд, занимающих длительное время.
• Реализация оператора RENAME DATABASE. Чтобы сделать это безопасным для
всех механизмов хранения, он должен работать следующим образом:
1. Создать новую базу данных.
2. Переименовать каждую таблицу в другую базу, как это делается командой
RENAME.
3. Удалить старую базу.
• Изменение нового внутреннего интерфейса файлов. Это обобщит управление
всеми файлами и станет возможным добавление расширений, подобных RAID.

1.6.4. Новые средства, запланированные


на ближайшее будущее
• Новая функциональность.
• Представления, реализованные в пошаговой манере, вплоть до полной функ-
циональности.
• Подобные Oracle конструкции CONNECT BY PRIOR оператора SELECT для извле-
чения древовидных иерархических структур.
• Добавление всех пропущенных стандартных типов SQL и ODBC 3.0.
• Добавление SUM (DISTINCT).
• INSERT SQL_CONCURRENT и mysqld --concurrent-insert ДЛЯ параллельной
вставки в конец таблицы, если таблица заблокирована по чтению.
44 Глава 1. Общая информация

• Разрешение обновления переменных оператором UPDATE, например, UPDATE


foo SET @a:=a+b, a=@a, b=@a+c.
• Когда пользовательские переменные изменены, разрешение использования их
в конструкции GROUP BY, как показано в следующем примере: SELECT i d ,
@a:=COUNT(*), SUM(sura_col)/@a FROM имя_таблицы GROUP BY id.
• Добавление опции IMAGE к LOAD DATA INFILE, чтобы не обновлять столбцы
TIMESTAMP И AUTO_INCREMENT.
• Добавление синтаксиса LOAD DATA INFILE.. .UPDATE, работающего следующим
образом:
• Для таблиц с первичными ключами, если вводимая запись имеет значение
первичного ключа, совпадающее с существующей записью, то последняя об-
новляется значениями столбцов вводимой записи. Столбцы, пропущенные во
вводимой записи, остаются без изменений.
• Для таблиц с первичными ключами, если вводимая запись не содержит пер-
вичного ключа, или же какая-то часть ключа пропущена, запись обрабатывает-
ся как LOAD DATA INFILE...REPLACE INTO.
• Изменение оператора LOAD DATA INFILE, чтобы стал возможным такой синтаксис:
LOAD DATA INFILE 'имя_файлa.txt f INTO TABLE имя_таблицы
TEXT_FIELDS (текстовый_столбец1, текстовый_столбец2, текстовый_столбецЗ)
SET столбец_таблицы!=CONCAT[текстовый_столбец1, текстовый_столбец2),
текстовый_столбецЗ=23
IGNORE текстовый_столбецЗ
Это может использоваться для того, чтобы пропустить лишние столбцы в тексто-
вом файле или обновить столбцы на основе выражения, составленного из прочи-
танных данных.
• Новые функции для работы со столбцами типа SET:
• ADD_TO_SET{значение, набор)
• REMOVE_FROM_SET{значение, набор)
Ш В настоящее время, если выполнение mysql прерывается посреди запроса, нужно
открыть другое соединение и уничтожить этот выполняющийся запрос. Необхо-
димо сделать так, чтобы такую ситуацию обнаруживал и разрешал сам сервер.
• Добавление интерфейса механизма хранения для табличной информации таким
образом, чтобы его можно было использовать как системную таблицу. Это может
несколько снизить скорость, если запрашивается информация обо всех таблицах,
однако существенно увеличится гибкость. Необходимо реализовать SHOW INFO
FROM имя__таблицы для базовой информации о таблице.
• Реализация SELECT a FROM имя_таблицы1 LEFT JOIN имя_таблицы2 USING (a) ;
здесь предполагается, что а поступает из таблицы имя__таблицы1.
• Добавление опций DELETE и REPLACE к оператору UPDATE (чтобы при возникнове-
нии ошибки, связанной с дублированием ключа во время обновления, строки
удалялись).
• Изменение формата DATETIME, чтобы можно было хранить доли секунды.
1.6. MySQL и будущее (списки TODO) 45

• Обеспечение возможности использования новой библиотеки GNU regexp вместо


применяемой сейчас (новая библиотека значительно быстрее).
• Соответствие стандартам, переносимость и миграция.
• Не добавлять автоматически значения по умолчанию к столбцам (DEFAULT).
Генерировать ошибку для любого оператора INSERT, в котором пропущены
значения столбцов, не имеющих значений DEFAULT.
• Добавить групповые функции ANY (), EVERY () и SOME (). В стандартном языке
SQL это работает только на столбцах с булевскими значениями, но мы можем
расширить это для работы на всех столбцах или выражениях, трактуя нулевые
значения как FALSE и ненулевые как TRUE.
• Исправить тип возврата функции МАХ (столбец), чтобы она возвращала тот же
тип, что и ее аргумент:
raysql> CREATE TABLE t l (a DATE);
mysql> INSERT INTO t l VALUES (NOW());
mysql> CREATE TABLE t 2 SELECT MAX (a) FROM t l ;
mysql> SHOW COLUMNS FROM t 2 ;
• Увеличение скорости.
• He разрешать создание большего, чем определено, количества потоков при
запуске восстановления My ISAM в одно и то же время.
• Изменить оператор INSERT INTO.. .SELECT так, чтобы можно было при жела-
нии использовать параллельные вставки.
• Добавить опцию периодического сбрасывания ключевых страниц для таблиц с
задержанными ключами, если они долго не используются.
• Разрешить объединения на частях ключей (для целей оптимизации).
• Добавить анализатор файлов протоколов, чтобы можно было извлекать ин-
формацию о том, какие таблицы используются наиболее часто, насколько час-
то запрашиваются многотабличные объединения и так далее. Это поможет
пользователям идентифицировать то, что подлежит оптимизации для более
эффективного выполнения запросов.
• Удобство использования.
• Возвращать оригинальный тип столбца при выполнении SELECT MIN(column)
. . . GROUP BY.
• Обеспечить возможность указывать long_query_time с точностью до миллисе-
кунд.
• Скомпоновать код myisampack с сервером, чтобы он мог выполнять операции
PACK И COMPRESS.
• Добавить временный буфер кэша ключей при выполнении INSERT, DELETE и
UPDATE с тем, чтобы стало возможным восстановление в случае переполнения
индексного файла.
• Если выполняется оператор ALTER TABLE для таблицы, указанной через симво-
лическую ссылку и расположенной на другом диске, создавать временные
таблицы на том же диске.
46 Глава 1. Общая информация

• Реализовать типы DATE и DATETIME так, чтобы они корректно обрабатывали


информацию о временных зонах, тем самым упростив работу с датами в раз-
ных зонах.
• Исправить configure, чтобы все библиотеки (подобно My ISAM) могли быть
скомпилированы без потоков.
• Разрешить применение пользовательских переменных в качестве аргументов
LIMIT, например: LIMIT @а, @b.
• Добавить автоматический вывод mysql в Web-браузер.
• Добавить LOCK DATABASES (с различными опциями).
• Дополнительная информация для SHOW STATUS. Чтение и обновление записей.
Запросы к отдельным таблицам и запросы к объединениям. Среднее количество
таблиц в запросе. Количество запросов с конструкциями ORDER BY и GROUP BY.
• Операция копирования mysqladmin copy база_данных новая_база_данных;.
Это потребует добавления операции COPY в mysqld.
• Вывод списка процессов должен показывать количество запросов/потоков.
• SHOW HOSTS для вывода информации о кэше имен хостов.
• Изменить имена таблиц с пустой строки на NULL для вычисляемых столбцов.
• Не использовать Item_copy_string для числовых значений, чтобы избежать
преобразования число-строка-число в случае наподобие:
SELECT COUNT(*)*(id+0) FROM имя_таблицы GROUP BY i d

• Изменить оператор ALTER TABLE таким образом, чтобы он не прерывал клиен-


тов, ВЫПОЛНЯЮЩИХ INSERT DELAYED.
• Внести исправление, чтобы при ссылке на столбцы в конструкции UPDATE они
содержали старые значения, которые были до начала обновления.
• Новые операционные системы.
• Перенести MySQL на платформу LynxOS.

1.6.5. Новые средства, запланированные на отдаленное


будущее
• Реализация функции get_changed_tables {тайм-аут, таблица!, таблица2, . . . ) .
• Изменить чтение таблиц так, чтобы использовалась mmap (), где это возможно. В
настоящее время mmap () используют только сжатые таблицы.
• Сделать код автоматических временных меток более изящным. Добавить автома-
тические временные метки в протокол обновлений с SET TI ME STAMP=значение;
• Использовать семафоры чтения-записи в некоторых местах для повышения ско-
рости.
• Автоматически закрывать некоторые таблицы, если таблица, временная таблица
или временный файл получают ошибку 23 (слишком много открытых файлов).
• Улучшенное распространение констант. Когда в выражении встречается
имя_столбца=п, причем п - константа, заменять все вхождения имя__столбца в вы-
ражении на п. В настоящее время это выполняется только в некоторых случаях.
1.6. MySQL и будущее (списки TODO) 47

• Заменить все константные выражения вычисляемыми, если возможно.


• Оптимизировать сравнения ключ = выражение. В настоящее время оптимизируются
только ключ = столбец и ключ - константа.
• Объединить некоторые функции копирования для получения более изящного кода.
• Заменить sql_yacc.yy на встроенный анализатор, чтобы уменьшить его размер и
получить более удобную диагностику ошибок.
• Изменить анализатор таким образом, чтобы использовать только одно правило
для разного числа аргументов функции.
• Использовать полные вычисленные имена в порядковой части (для СУБД Access 97).
• Реализовать MINUS, INTERSECT и FULL OUTER JOIN (сейчас поддерживаются UNION и
LEFT | RIGHT OUTER JOIN).
• Разрешить использование SQLJDPTION MAX_SELECT_TIME=значение для указания
временного ограничения в запросе.
• Сделать возможной запись протоколов обновлений в базу данных.
• Усовершенствовать LIMIT, чтобы обеспечить извлечение данных из конца резуль-
тирующего набора.
• Организовать выдачу предупреждений клиентскими функциями подключе-
ния/чтения/записи.
• Обратите внимание на изменения в mysqld_safe: согласно стандарту FSSTND
(которому старается следовать Debian), PID-файлы должны размещаться в
/уаг/гип/<имя_программы>.р1с1, а файлы протоколов - в /var/log. Было бы не-
плохо, если бы можно было помещать "DATADIR" в первое объявление "pidfile"
и "log", чтобы местоположение этих файлов можно было менять с помощью
единственного оператора.
• Разрешить клиенту запрашивать протоколирование.
• Разрешить оператору LOAD DATA INFILE читать файлы, сжатые с помощью дzip.
• Исправить сортировку и группирование столбцов BLOB (частично решено сейчас).
• Использовать семафоры при подсчете потоков. Сначала потребуется реализовать
библиотеку семафоров для потоков MIT-pthreads.
• Добавить полную поддержку JOIN со скобками.
• В качестве альтернативы модели "один поток на соединение" управлять пулом
потоков для управления запросами.
• Разрешить GETLOCK () получать более одной блокировки. При этом обрабатывать
возможные взаимные блокировки, к которым это усовершенствование может
привести.

1.6.6. Новые средства, которые не планируются


к реализации
Наша цель состоит в достижении как можно более полной совместимости со стан-
дартом ANSI/ISO SQL. Нет таких средств, которые мы НЕ планируем реализовывать.
48 Глава 1. Общая информация

1.7. Источники информации по MySQL


1.7.1. Списки рассылки MySQL
В этом разделе представлены списки рассылки MySQL и руководство по их исполь-
зованию. После того, как вы подпишетесь на список рассылки, вам начнет поступать вся
корреспонденция из этого списка по электронной почте. Кроме того, вы сможете от-
правлять свои вопросы, а также ответы на вопросы других подписчиков.

1.7.1.1. Перечень списков рассылки MySQL


Чтобы подписаться или отказаться от подписки на любой список рассылки, упоми-
наемый в настоящем разделе, зайдите на http://lists.mysql.com. Не посылайте запро-
сов на подписку или отказ от подписки в любой их списков, поскольку такие письма
автоматически рассылаются тысячам подписчиков.
Ваш локальный сайт может иметь множество подписчиков на списки рассылки
MySQL. Если это так, имеет смысл завести локальные списки рассылки, чтобы сообще-
ния, отправленные на lists.mysql.com, рассылались адресатам, занесенным в них. В
этом случае обратитесь к системному администратору, чтобы он внес вас в локальный
список рассылки MySQL.
Если вы желаете, чтобы сообщения из рассылки попадали в отдельный почтовый
ящик в вашей почтовой программе, настройте фильтр на базе заголовков сообщений.
Для идентификации этих сообщений можно использовать заголовки List-ID: или
Delivered-TO:.
Ниже представлены списки рассылки MySQL.
• anounce
Это рассылка объявлений о новых версиях MySQL и сопутствующих программ.
Это рассылка с малой активностью; на нее должны быть подписаны все пользова-
тели MySQL.
• mysql
Это основная рассылка для общих дискуссий по вопросам MySQL. Стоит заме-
тить, что некоторые темы более подробно обсуждаются в специальных рассылках.
Если вы отправите письмо не в ту рассылку, то, вероятно, не получите ответа.
• mysql-digest
Это рассылка mysql в форме дайджеста. Если вы подпишетесь на эту рассылку, то
будете ежедневно получать группу сообщений одним письмом.
• bugs
Эта рассылка может быть интересна, если вы хотите быть в курсе сообщений о
последней версии MySQL или желаете включиться в процесс поиска и исправле-
ния ошибок.
• bugs-digest
Это рассылка bugs в форме дайджеста.
• internals
Эта рассылка предназначена в основном для тех, кто имеет дело с кодом MySQL.
Это также форум для дискуссий о разработке MySQL и рассылки исправлений.
• internals-digest
Это рассылка internals в форме дайджеста.
1.7. Источники информации по MySQL 49

• mysqldoc
Эта рассылка для тех, кто работает над созданием документации MySQL: людей
из MySQL AB, переводчиков и других членов сообщества.
• mysqldoc-digest
Это рассылка mysqldoc в форме дайджеста.
• benchmarks
Это рассылка для тех, кого интересуют вопросы производительности. Дискуссии
сосредоточены вокруг производительности СУБД (не только MySQL), а также ка-
саются более широких категорий, включая производительность ядра, файловых
систем, дисковых систем и так далее.
• benchmarks-digest
Это рассылка benchmarks в форме дайджеста.
• packagers
Это рассылка для дискуссий об объединении в пакеты и распространении MySQL.
В данном форуме участвуют те, кто занимается поддержкой распространения для
обмена идеями о том, как формировать пакеты MySQL и как добиваться того,
чтобы MySQL выглядел и работал насколько возможно единообразно на всех
платформах и операционных системах.
• packagers-digest
Это рассылка packagers в форме дайджеста
• Java
Это рассылка для дискуссий, связанных с сервером MySQL и языком Java. В ос-
новном здесь обсуждаются JDBC-драйвера, включая MySQL Connector/J.
• java-digest
Это рассылка j ava в форме дайджеста.
• Win32
Этот список предназначен для обсуждения всего, что касается использования
MySQL под управлением операционных систем семейства Microsoft, таких как
Windows 9x, Me, NT, 2000 и ХР.
• win32-digest
Это рассылка Win32 в форме дайджеста.
• myodbc
Эта рассылка относится ко всему, что связано с подключением к MySQL через
ODBC.
• myodbc-digest
Это рассылка myodbc в форме дайджеста.
• gui-tools
Здесь обсуждаются инструменты MySQL с графическим интерфейсом пользова-
теля, включая MySQL Administrator и графический клиент MySQL Control Center.
• gui-tools-digest
Это рассылка gui-tools в форме дайджеста.
• plusplus
Этот список рассылки касается вопросов программирования на C++ для MySQL.
50 Глава 1. Общая информация

• plusplus-digest
Это рассылка plusplus в форме дайджеста.
• msql-mysql-modules
Эта рассылка для всех вопросов, связанных с поддержкой MySQL языка Perl, в
частности, модулем DBD:mysql.
• msql-mysql-modules-digest
Это рассылка msql-mysql-modules в форме дайджеста.
Если вы не можете получить ответ на заданный вопрос в списках рассылки MySQL,
выходом может быть заключение договора поддержки с компанией MySQL AB. Это
позволит вам напрямую контактировать с разработчиками MySQL (см. раздел 1.4.1).
Ниже представлен перечень списков рассылки MySQL на других языках (кроме анг-
лийского). Эти рассылки компанией MySQL AB не управляются.
[email protected]
Список рассылки на французском языке.
[email protected]
Список рассылки на корейском языке. Для подписки отправьте по адресу списка
сообщение subscribe mysql ваш@почтовый, адрес.
[email protected]
Список рассылки на немецком языке. Для подписки отправьте по адресу списка
сообщение subscribe mysql-de ваш@почтовый. адрес. Дополнительную информа-
цию об этом списке можно найти по адресу h t t p : //www. 4t2.com/mysql.
[email protected]
Список рассылки на португальском языке. Для подписки отправьте по адресу
списка сообщение subscribe mysql-br ваш@почтовый.адрес.
[email protected]
Список рассылки на испанском языке. Для подписки отправьте по адресу списка
сообщение subscribe mysql ваш@почтовый.адрес.

1.7.1.2. Как задавать вопросы и сообщать об ошибках


Прежде чем посылать вопрос или сообщение об ошибке, выполните следующие дей-
ствия:
• Начните с поиска в онлайновом руководстве по MySQL на http: / /dev. mysql. com/doc/.
Мы стараемся поддерживать это руководство в актуальном состоянии, часто об-
новляя его по мере решения обнаруженных проблем. Полезной может оказаться и
хронология изменений (http: //dev. mysql. com/doc/mysql/en/News .html), по-
скольку весьма вероятно, что в новых версиях та или иная проблема уже решена.
• Просмотрите базу данных ошибок, которая доступна по адресу
http://bugs.mysql.com/. Возможно, ошибка, о которой вы собираетесь сооб-
щить, уже обнаружена и исправлена.
• Поищите в архиве списков рассылки на http://lists.mysql.com/.
• Воспользуйтесь поисковой службой http://www.mysql.com/search/ для поиска
по всему Web-сайту MySQL AB, включая онлайновое руководство.
1.7. Источники информации по MySQL 51

Если вы не можете найти ответ в справочном руководстве и архивах, обратитесь к


местному эксперту по MySQL. Если и он не даст ответа на вопрос, то перед тем как свя-
заться с нами, изучите приведенную ниже инструкцию по отправке писем в списки рас-
сылки MySQL.

1.7.1.3. Как сообщать об ошибках и проблемах


Обычное место, куда нужно направлять сообщения об ошибках, это
http://bugs.mysql.com/ - адрес нашей базы данных ошибок. Эта база общедоступна,
любой может ее просматривать и выполнять в ней поиск. Если вы зарегистрируетесь в
системе, то также сможете вводить в нее новые сообщения.
Написание качественного отчета об ошибке требует немалого терпения, однако, со-
ставив его правильно, вы сэкономите как свое время, так и наше. Хороший отчет об
ошибке должен содержать полное описание пути, приводящего к ее проявлению (случай
тестирования); весьма вероятно, что мы исправим обнаруженную вами ошибку уже в
очередном выпуске. Сведения, представленные в этом разделе, посвящены тому, как
правильно составлять такие отчеты, дабы не пришлось впустую тратить время на то, что
либо мало поможет нам, либо вообще не поможет.
Для генерации отчета об ошибке (или сообщения о любой проблеме) мы рекоменду-
ем использовать сценарий mysqlbug. Упомянутый сценарий находится в каталоге
scripts (исходного дистрибутива) и в каталоге bin (бинарного дистрибутива MySQL).
Если запустить mysqlbug не удается (например, если вы работаете в среде Windows), все
равно важно включить всю необходимую информацию, указанную в настоящем разделе
(и самое главное - описание операционной системы и версии MySQL).
Сценарий mysqlbug поможет сгенерировать отчет об ошибке, собрав большую часть
информации автоматически, но кое-что важное придется ввести вручную. Внимательно
прочтите настоящий раздел и убедитесь, что вся перечисленная здесь информация
должным образом отражена в отчете.
Прежде всего, необходимо убедиться в наличии проблемы в последней производст-
венной версии MySQL или версии, находящейся на стадии разработки. Любой может
воспроизвести найденную ошибку, просто запустив mysql t e s t < файл^сценария или
же запустив Perl-сценарий, включенный в отчет об ошибке.
Все ошибки, отправленные в базу ошибок на http: //bugs .mysql. com/, будут исправлены
или документированы в следующем выпуске MySQL. Если исправление ошибки требует
только небольших изменений в коде, возможно, будет разослано только исправление.
Если вы обнаружили существенную ошибку в системе безопасности MySQL, сооб-
щение об этом необходимо прислать по адресу security@mysql. com.
Если вы подготовили воспроизводимый отчет об ошибке, присылайте его в базу
ошибок по адресу http://bugs.mysql.com/. Помните, что даже в этом случае желатель-
но запустить сценарий mysqlbug для сбора информации о вашей системе. Любая ошибка,
которую мы сможем воспроизвести, имеет хорошие шансы на то, чтобы быть исправ-
ленной в очередном выпуске MySQL.
Сообщения о проблемах иного рода можно отправлять в списки рассылки MySQL.
Помните, что мы можем ответить на сообщения, содержащие слишком много ин-
формации, но не можем ответить на те, что содержат ее слишком мало. Люди часто про-
пускают некоторые факты, поскольку думают, что имеют представление о причинах
проблем, и предполагают, что детали значения не имеют. Хороший принцип, которым
следует руководствоваться, может быть сформулирован следующим образом: если вы
52 Глава 1. Общая информация

сомневаетесь, стоит ли сообщать о чем-то, то сообщайте. Получится гораздо быстрее и


проще, если вы напишите кучу дополнительных строк в сообщении, чем если нам при-
дется запрашивать у вас дополнительную информацию, пропущенную в первичном со-
общении, и ждать ответа.
Наиболее часто встречающиеся ошибки в отчетах таковы: (а) не указан номер версии
используемого дистрибутива MySQL и (Ь) не полностью описана платформа, на которой
установлен сервер MySQL (включая тип платформы и номер версии). Это чрезвычайно
важная информация, и в 99 случаях из 100 сообщение об ошибке без нее бесполезно.
Очень часто мы получаем вопросы вроде такого: "Почему у меня то-то и то-то не рабо-
тает?" Потом выясняется, что возможность просто в данной версии MySQL не реализо-
вана, или же эта ошибка известна и исправлена в более новой версии MySQL. Иногда
ошибка оказывается зависимой от платформы и в этом случае мы не в состоянии испра-
вить что-либо, не зная операционной системы и номера ее версии.
Если вы скомпилировали MySQL из исходных текстов, не забудьте также указать
информацию о компиляторе, если это связано с проблемой. Часто люди сталкиваются с
ошибками компиляторов, а думают, что ошибки связаны с кодом MySQL. Большинство
компиляторов находятся в постоянном процессе разработки и становятся лучше от вер-
сии к версии. Чтобы определить, не вызвана ли проблема компилятором, нам надо знать,
какой компилятор вы используете. Помните, что любые проблемы с компиляцией долж-
ны рассматриваться как ошибки и сообщаться соответствующим образом.
Лучше всего, если в отчет об ошибке включено исчерпывающее описание проблемы.
Имеется в виду описание всего того, что вы делали и столкнулись с ошибкой, а также
подробное описание самой проблемы. То есть наилучшими отчетами об ошибках явля-
ются такие, которые содержат полный пример, показывающий, как воспроизвести опи-
санную ошибку или проблему.
Если какая-то программа выдает сообщение об ошибке, очень важно включить это
сообщение в отчет. Если мы попытаемся найти что-нибудь в архивах, лучше, чтобы со-
общение об ошибке, сгенерированное программой, было точно в том виде, как вы его
увидели (важен даже регистр символов). Никогда не пытайтесь воспроизвести по памяти
это сообщение, а вместо этого просто скопируйте его и вставьте в отправляемый отчет.
Если у вас возникла проблема с Connector/ODBC (MyODBC), пожалуйста, попытай-
тесь сгенерировать трассировочный файл MyODBC и прислать его вместе с отчетом.
Помните, что многие люди, которые будут читать ваш отчет об ошибке, используют
отображение с шириной 80 символов. Поэтому при генерации сообщения об ошибке с
помощью mysqlbug применяйте опцию --vertical (или символ завершения операторов
\G) для вывода, который может по ширине превысить общепринятые размеры (напри-
мер, с оператором EXPLAIN SELECT, как показано выше в примере).
В отправляемый отчет должна быть включена следующая информация:
• Номер версии используемого дистрибутива MySQL, например, MySQL 4.0.12.
Эту информацию можно получить, запустив mysqladmin version. Программа
mysqladmin расположена в подкаталоге bin каталога с инсталляцией MySQL.
• Производитель и модель компьютера, на котором возникла проблема.
• Наименование и версия операционной системы. Если вы работаете под управле-
нием Windows, получить эту информацию можно, выполнив двойной щелчок на
пиктограмме My Computer (Мой компьютер) и выбрав в меню Help (Справка)
пункт About (О программе). Для большинства Unix-подобных операционных сис-
тем эту информацию можно получить через команду uname -a.
1.7. Источники информации по MySQL 53

• Иногда важен объем памяти (физической и виртуальной). При наличии каких-


либо сомнений, включите в отчет и эту информацию.
• Если вы используете дистрибутив MySQL с исходными текстами, понадобится
наименование и номер версии компилятора. Если дистрибутив только бинарный,
потребуется его наименование.
• Если проблема возникает при компиляции, включите в отчет сообщение об ошиб-
ке компилятора и несколько строк из контекста, окружающего то место в исход-
ном коде, где возникла ошибка.
• Если mysqld аварийно завершился, сообщите в отчете текст запроса, приводящего
к таким последствиям. Обычно это можно сделать, запустив mysqld с включенной
опцией протоколирования запросов и заглянув в файл протокола после отказа
mysqld.
• Если к ошибке имеет отношение таблица базы данных, включите вывод
mysqldump —nodata имя_базы_данных имя_таблицы. Это очень просто сделать и это
отличный способ получить информацию о любой таблице в базе данных. В резуль-
тате у нас появится возможность смоделировать сложившуюся у вас ситуацию.
• При описании проблем, имеющих отношение к скорости или к оператору SELECT,
всегда необходимо включать вывод команды EXPLAIN SELECT . . . , а также, по
меньшей мере, число строк, которое возвращает оператор SELECT. Также следует
включить вывод команды SHOW CREATE TABLE имя^таблицы для каждой таблицы,
участвующей в запросе. Чем больше информации о ситуации вы сообщите, тем
более вероятно, что кто-то сможет вам помочь. Ниже представлен пример очень
хорошего отчета об ошибке. Он может быть отправлен через сценарий mysqlbug.
Этот пример использует утилиту командной строки mysql. Отметьте применение
ограничителя операторов \G для тех из них, чей вывод превышает ширину ото-
бражения в 80 символов:
mysql> SHOW VARIABLES;
mysql> SHOW COLUMNS FROM . . . \ G
<вывод SHOW COLUMNS>
mysql> EXPLAIN SELECT . . . \ G
<вывод EXPLAIN>
mysql> FLUSH STATUS;
mysql> SELECT . . . ;
Сокращенная версия вывода SELECT,
включая время выполнения запроса>
mysql> SHOW STATUS;
<вывод SHOW STATUS>

• Если ошибка или проблема возникает во время работы mysqld, постарайтесь


предоставить сценарий, который воспроизводит аномалию. Этот сценарий
должен включать все необходимые исходные файлы. Чем ближе к реальности
сценарий сможет воспроизвести ситуацию, тем лучше. Если вы можете соста-
вить воспроизводимый случай тестирования, присылайте его по адресу
http://bugs.mysql.com/ для высокоприоритетной обработки. Если вы не можете
предоставить сценарий, по крайней мере, включите в отчет вывод команды
mysqladmin variables extended-status processlist, чтобы дать представление
о том, как ваша система настроена.
54 Глава 1. Общая информация

• Если вы не можете предоставить случай тестирования в нескольких строках или


же случай тестирования слишком большой, чтобы присылать его в группу рас-
сылки (более 10 строк), вам потребуется сбросить дамп таблиц с помощью
mysqldump и создать файл README с описанием проблемы. Создайте архив своих
файлов с помощью утилит tar, gzip или zip и отправьте его через FTP-протокол
по адресу ftp://ftp.mysql.cora/pub/mysql/upload/. Затем введите описание про-
блемы в базу данных ошибок по адресу h t t p : //bugs .mysql. com/.
• Если вам кажется, что MySQL выдает странный результат запроса, включите не
только собственно результат, а также ваше предположение, каким он должен
быть, и опишите основания своих предположений относительно результата.
• При описании примера возникновения проблемы лучше использовать имена пе-
ременных, таблиц и так далее такими, какими они были в вашей ситуации, а не
придумывать новые имена. Проблема может иметь отношение к имени перемен-
ной или таблицы. Это случается редко, но лучше подстраховаться и не вносить
искажений в описание проблемы. К тому же вам будет проще, да и нам удобней,
если вы приведете пример реальной ситуации. Если у вас есть данные, которые
вы не хотите показывать всем, их можно отправить через FTP-протокол по адресу
ftp://ftp.mysql.com/pub/mysql/upload. Если же информация настолько секрет-
на, что вы не хотите ее показывать даже нам, тогда приводите пример с изменен-
ными именами, но это только в крайнем случае.
• Включите в отчет все опции всех программ, имеющих отношение к ошибочной
ситуации, если это возможно. Так, например, укажите опции, которые вы исполь-
зовали для запуска сервера mysqld, как и опции любых клиентских программ
MySQL. Опции программ mysqld, mysql, сценария configure часто являются клю-
чами к ответу и поэтому очень важны. Никогда не стоит пренебрегать этим. Если
вы применяете модули, подобные Perl или РНР, пожалуйста, укажите номера их
версий.
• Если ваш вопрос имеет отношение к системе привилегий, включите в отчет вывод
утилит mysqlaccess, mysqladmin reload и все сообщения об ошибках, которые
выдаются при попытке подключения. Когда вы проверяете существующие приви-
легии, то должны сначала запустить mysqlaccess. После этого запустите
mysqladmin reload version и попытайтесь подключиться с помощью той про-
граммы, которая приводила к проблемам.
• Если вы располагаете модулем исправления ошибки, упомяните в отчете и о нем.
Однако не ожидайте, что ваш модуль исправления - это все, что нам нужно или
что мы его используем, особенно если переданный отчет об ошибке не включает в
себя случай тестирования, который воспроизводит ошибку, фиксируемую моду-
лем исправления. Мы можем обнаружить проблемы, связанные с вашим модулем
исправления, или вообще не понять его. Если так случится, мы не станем его ис-
пользовать. Если мы не можем проверить, для чего предназначен данный модуль
исправления, мы также не станем его использовать. В этом нам помогут случаи
тестирования. Покажите, что модуль исправления справляется со всеми ситуа-
циями, которые могут возникнуть. Если мы обнаружим какие-то ограничения
(даже очень редкие), при которых модуль исправления не работает, он может не
пригодиться.
1.7. Источники информации по MySQL 55

• Предположения о природе обнаруженной ошибки, причинах ее возникновения


или зависимостях, как правило, неверны. Даже группа разработчиков MySQL не
может делать каких-то предположений, пока не воспользуется средствами отлад-
ки для нахождения истинной причины ошибки.
• Отмечайте в отчете об ошибке, что вы просматривали руководство и архивы спи-
сков рассылки, чтобы остальные знали, что вы пытались решить проблему само-
стоятельно.
• Если вы получили сообщение об ошибке "parse error" ("ошибка синтаксического
анализа"), тщательно проверьте код на предмет корректности синтаксиса. Если вы
не находите в нем ничего некорректного, вполне возможно, что ваша версия сер-
вера MySQL не поддерживает используемый вами синтаксис. Если вы используе-
те текущую версию сервера и руководство на h t t p : //dev.mysql.com/doc/ не опи-
сывает применяемый вами синтаксис, значит, сервер MySQL подобный запрос
не поддерживает. В этом случае единственный выход для вас - реализовать
требуемый синтаксис самостоятельно или отправить письмо по адресу
licensing@mysql. com с просьбой реализовать его. Если в руководстве описан син-
таксис, который вы применяете, но у вас более старая версия сервера MySQL,
стоит просмотреть хронологию изменений MySQL, чтобы найти, когда этот син-
таксис был реализован. В этом случае у вас есть возможность обновить сервер
MySQL до более новой версии.
• Если возникшая проблема связана с повреждением данных, либо ошибки возни-
кают при попытке обращения к отдельной таблице, потребуется сначала прове-
рить, а затем восстановить таблицы с помощью команд CHECK TABLE и REPAIR
TABLE, либо с помощью утилиты myisamchk. Если вы работаете в среде Windows,
убедитесь, что команда SHOW VARIABLES LIKE 'lower_case_table_names' возвра-
щает значение 1 или 2.
• Если повреждения таблиц случаются часто, попытайтесь выяснить, когда и поче-
му это происходит. В этом случае протокол ошибок в словаре данных MySQL
может содержать некоторую информацию о том, что происходит. (Это файл с
суффиксом .err в имени). Включите в отчет об ошибке любую важную информа-
цию из этого файла. Обычно mysqld никогда не портит таблиц, если только ничто
не уничтожает его в процессе обновления данных. Если вы сможете выяснить при-
чину краха mysqld, нам будет значительно легче помочь вам решить проблему.
• Если возможно, загрузите и установите самую последнюю версию сервера
MySQL и проверьте, осталась ли проблема нерешенной. Все версии программного
обеспечения MySQL тестируются очень тщательно и должны функционировать без
проблем. Мы стараемся обеспечить обратную совместимость, насколько это воз-
можно, поэтому переход на новую версию должен пройти без особых проблем.
Если вы - клиент, заключивший с нами договор поддержки, перешлите отчет об
ошибке по адресу [email protected] для высокоприоритетной обработки, а так-
же отправьте этот отчет в соответствующий список рассылки, чтобы проверить, не стал-
кивался ли кто-нибудь с подобной проблемой и, возможно, каким-то образом решил ее.
Если ответы направляются вам персонально, а не в группу рассылки, хорошим тоном
считается резюмировать ответы и отправлять их в список рассылки, чтобы другие под-
писчики тоже получили пользу от ответов, которые помогли вам решить возникшую
проблему.
56 Глава 1. Общая информация

1.7.1.4. Рекомендации по составлению ответов на вопросы


из списков рассылки
Если вы считаете, что ваш ответ может заинтересовать многих, возможно, имеет
смысл отправить его в список рассылки вместо того, чтобы отвечать персонально тому,
кто задал вопрос. Постарайтесь максимально обобщить ответ, дабы он принес пользу и
другим, а не только тому, кто спрашивает. Отправляя ответ в список рассылки, убеди-
тесь, что он не дублирует предыдущие ответы на тот же вопрос. Постарайтесь подыто-
жить существенную часть вопроса в ответе, но не считайте необходимым полностью
цитировать оригинальный вопрос.
Не отправляйте почтовых сообщений с помощью браузера с включенным режимом
HTML. Многие пользователи читают письма, не прибегая к услугам браузера.

1.7.2. Поддержка сообщества пользователей MySQL в IRC


В дополнение к спискам рассылки MySQL опытных пользователей можно найти и в
IRC (Internet Relay Chat - беседы в Internet). Ниже перечислены лучшие сети/каналы,
известные на данный момент.
• freenode (http://www.freenode.net/)
• #mysql. В основном обсуждаются вопросы, связанные с MySQL, но можно за-
давать вопросы и по другим СУБД и SQL.
• #mysqlphp. Вопросы, связанные с использованием популярной комбинации
продуктов - MySQL + PHP.
• #mysqlperl. Вопросы, связанные с использованием другой популярной
комбинации продуктов - MySQL + Perl.
• EFnet (http://www.efnet.org/)
• #mysql. Вопросы по MySQL.
Если вам необходимо программное обеспечение IRC-клиента для подключения к се-
тям IRC, рекомендуем воспользоваться X-Chat (http://www.xchat.org/). X-Chat (регла-
ментируется лицензией GPL) доступен как для Unix-, так и для Windows-платформ.

1.8. Соответствие стандартам MySQL


В этом разделе представлена информация, касающаяся того, как MySQL соотносится
со стандартами ANSI/ISO SQL. В сервере MySQL реализовано множество расширений
стандарта SQL, и здесь вы найдете сведения о том, что они собой представляют и как их
использовать. Кроме того, представлена информация о функциональности, которая от-
сутствует в сервере MySQL, а также о том, как преодолевать некоторые расхождения со
стандартом.
Стандарт SQL появился в 1986 году и на сегодняшний день существует несколько
его версий. В настоящем руководстве "SQL-92" ссылается на стандарт, изданный в 1992
году, "SQL: 1999" - на стандарт, изданный в 1999 году, и "SQL:2003" - на текущую вер-
сию стандарта. Под "стандартом SQL" понимается последняя версия стандарта.
Наша цель состоит в том, чтобы не сужать рамки применения сервера MySQL без
веских на то причин. Даже если у нас не хватает ресурсов для разработки, ориентиро-
ванной на любое возможное применение, мы всегда стараемся оказать помощь людям,
которые пытаются применять сервер MySQL в новых областях.
1.8. Соответствие стандартам MySQL 57

Одна из главных задач при разработке этого продукта состоит в том, чтобы продол-
жать работу в направлении максимального соответствия стандарту SQL, однако, не
жертвуя при этом производительностью и надежностью. Мы не боимся добавлять собст-
венные расширения к SQL или поддерживать не-SQL средства, если это значительно
увеличивает удобство применения сервера MySQL для большого сегмента нашей поль-
зовательской базы. Примером такой стратегии может служить интерфейс HANDLER в сер-
вере MySQL 4.O.
Мы будем продолжать поддержку транзакционной и не-транзакционной баз данных,
чтобы удовлетворить запросы как тех пользователей, которым нужна работа с ответст-
венными данными по схеме "24 часа в сутки, 7 дней в неделю", так и тех, кому необхо-
дима напряженная работа с Web и регистрацией.
Изначально сервер MySQL разрабатывался для баз данных средних размеров (10-100
миллионов записей, или около 100 Мбайт на таблицу) в малых компьютерных системах.
Сегодня сервер MySQL обслуживает терабайтные базы данных, но его код по-прежнему
может быть скомпилирован в ограниченную версию, применимую в портативных и
встроенных системах. Компактный дизайн сервера MySQL делает возможным продол-
жение разработки в обоих направлениях, без каких-либо конфликтов в дереве исходного
кода.
В настоящее время мы не планируем поддержку систем реального времени, но, не-
смотря на это, средства репликации MySQL уже предлагают достаточно развитую функ-
циональность.
Поддержка кластеризованных баз данных планируется на основе интеграции приоб-
ретенной нами технологии NDB-кластеров с новым механизмом хранения, который стал
доступным в 2004 году.
Мы также готовимся предоставить поддержку XML на сервере баз данных.

1.8.1. Стандарты, которым соответствует MySQL


Мы нацелены на реализацию полной поддержки стандарта ANSI/ISO, но без ком-
промиссов в отношении производительности и качества кода.
ODBC уровней 0-3.51.

1.8.2. Выбор режимов SQL


Сервер MySQL может работать в различных режимах SQL и может по-разному при-
менять эти режимы для различных клиентов. Это дает приложениям возможность при-
спосабливать функционирование сервера к существующим требованиям.
Режимы определяют, какой синтаксис SQL должен поддерживать сервер MySQL и
какой тип проверок он должен выполнять для данных. Это позволяет использовать
MySQL во множестве различных сред, а также применять его вместе с другими сервера-
ми баз данных.
Режим SQL по умолчанию устанавливается во время запуска mysqld с помощью
опции --sql-mode="modes". Начиная с MySQL 4.1, можно изменять режим после за-
пуска сервера путем установки переменной sqljnode с помощью оператора SET
[SESSION|GLOBAL] sql_mode='modes'.

1.8.3. Запуск MySQL в режиме ANSI


Чтобы перевести mysqld в ANSI-режим, запустите его с опцией —ansi.
58 Глава 1. Общая информация

Выполнение сервера в режиме ANSI эквивалентно его запуску со следующими оп-


циями (значения —sql-mode должны указываться в одной строке):
--transaction-isolation=SERIALIZABLE
—sql-mode=REAL_AS_FLOAT,PIPES_AS_CONCAT/ANSI_QUOTESf
IGNORE_SPACE,ONLY_FULL_GROUP_BY
В MySQL 4.1 можно получить тот же результат с помощью следующих операторов:
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET GLOBAL sql_mode = 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,
IGNORE_SPACE,ONLY_FULL_GROUP_BY';
См. раздел 1.8.2.
В MySQL 4.1.1 опция sqljnode может быть также установлена так, как показано ниже:
SET GLOBAL sql_mode='ansi';
В этом случае значением переменной sqljnode будут все опции, имеющие отноше-
ние к режиму ANSI. Вы можете проверить это так:
mysql> SET GLOBAL sql_mode='ansi';
mysql> SELECT @@global.sqljnode;
-> 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,
IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI';

1.8.4. Расширения стандартного SQL в MySQL


В состав сервера MySQL входит ряд расширений, которых, возможно, вы не найдете
в других базах данных SQL. Помните, что если вы используете их, ваш код перестанет
быть переносимым на другие серверы SQL. В некоторых случаях вы можете писать код,
включающий расширения MySQL, но остающийся переносимым, используя для этого
форму комментариев /*! . . . */. В этом случае сервер MySQL разбирает и выполняет
код внутри комментария, как и любые другие SQL-операторы, а все другие серверы SQL
расширение проигнорируют. Например:
SELECT /*! STRAIGHT_JOIN */ имя_столбца FROM таблица1,таблица2 WHERE . . .
Если после символа '!' добавить номер версии, синтаксис внутри комментария будет
выполняться только сервером MySQL указанной и более поздних версий:
CREATE /*132302 TEMPORARY */ TABLE t (a INT);
Это означает, что если работа выполняется в версии MySQL 3.23.02 или более позд-
ней, то ключевое слово TEMPORARY будет использовано.
В приведенном ниже списке описаны расширения MySQL по категориям.
• Организация данных на диске.
Сервер MySQL отображает каждую базу данных на подкаталог внутри каталога
данных MySQL, а таблицы внутри базы - на имена файлов в этом каталоге. От-
сюда вытекает несколько следствий:
• Имена баз данных и таблиц MySQL зависят от регистра в средах операцион-
ных систем, в которых имена файлов чувствительны к регистру символов
(большинство Unix-систем).
• Можно использовать стандартные системные команды для резервного копиро-
вания, переименования, перемещения, удаления и копирования таблиц, управ-
1.8. Соответствие стандартам MySQL 59

ляемых механизмами хранения My ISAM или ISAM. Например, чтобы переимено-


вать таблицу MylSAM, потребуется переименовать файлы .MYD, .MYI и .frm, ко-
торые относятся к таблице.
Имена баз данных, таблиц, индексов, столбцов и псевдонимы могут начинаться с
цифры (но не должны состоять только из цифр).
• Общий синтаксис языка.
• Строки могут ограничиваться и одиночными и двойными кавычками.
• Символ 'V используется в строках как управляющий.
• Внутри SQL-операторов можно получать доступ к таблицам из разных баз дан-
ных посредством синтаксиса имя_базы_данных. имя__таблицы. Некоторые серверы
SQL предоставляют ту же функциональность, но называют ее пространством
пользователя (User space). Сервер MySQL не поддерживает табличных про-
странств, как в следующем операторе: CREATE TABLE r a l p h . m y _ t a b l e . . .IN
my_tablespace.
• Синтаксис SQL-операторов.
• О п е р а т о р ы ANALYZE TABLE, CHECK TABLE, OPTIMIZE TABLE И REPAIR TABLE.
• О п е р а т о р ы CREATE DATABASE И DROP DATABASE.
• Оператор DO.
• EXPLAIN SELECT - для получения описания способа объединения таблиц в за-
просе.
• Операторы FLUSH и RESET.
• Оператор SET.
• Оператор SHOW.
• LOAD DATA INFILE. Во многих случаях этот синтаксис совместим с аналогич-
ным синтаксисом Oracle.
• RENAME TABLE.
• REPLACE вместо DELETE + INSERT.
• Конструкции CHANGE имя^столбца, DROP имя_столбца, DROP INDEX, IGNORE и
RENAME в операторе ALTER TABLE. Использование множественных конструкций
ADD, ALTER, DROP И CHANGE В о п е р а т о р е ALTER TABLE.
• Использование имен индексов, индексов в префиксах полей, а также конст-
рукций INDEX ИЛИ KEY В операторе CREATE TABLE.
• Использование IF EXISTS вместе с DROP TABLE.
• Можно удалять несколько таблиц одним оператором DROP TABLE.
• Конструкции ORDER BY и LIMIT в операторах UPDATE и DELETE.
• Синтаксис INSERT INTO...SET имя_столбца =
• Конструкция DELAYED в операторах INSERT и REPLACE.
• Конструкция LOW_PRIORITY В операторах INSERT, REPLACE, DELETE И UPDATE.
• Использование INTO OUTFILE и STRAIGHT_JOIN в операторе SELECT.
• ОПЦИЯ SQL_SMALL_RESULT оператора SELECT.
60 Глава 1. Общая информация

• Нет необходимости перечислять все выбранные столбцы в конструкции GROUP


BY. Это обеспечивает лучшую производительность для некоторых очень спе-
цифических, но вполне нормальных запросов.
• Можно применять ASC или DESC вместе с GROUP BY.
• Имеется возможность присваивать значения переменным с помощью операции
присваивания : = в операторах:
mysql> SELECT @a:=SUM(total),@b=COUNT(*),@a/@b AS avg
-> FROM t e s t _ t a b l e ;
mysql> SELECT @tl:=(@t2:=l)+@t3:=4,@tl,@t2,@t3;
• Типы столбцов.
• Типы столбцов MEDIUMINT, SET, ENUM и различные варианты типов BLOB и TEXT.
• Атрибуты столбцов AUTO_INCREMENT, BINARY, NULL, UNSIGNED И ZEROFILL.
• Функции и операции.
• Чтобы облегчить жизнь пользователям, привыкшим к другим SQL-средам,
сервер MySQL поддерживает псевдонимы для многих функций. Например, все
строковые функции поддерживают как стандартный синтаксис SQL, так и син-
таксис ODBC.
• Сервер MySQL воспринимает операции && и | | как логическое " И " (AND) и
логическое "ИЛИ" (OR), по аналогии с языком программирования С. В кон-
тексте сервера MySQL операции | | и OR являются синонимами, равно как и & &
и AND. По этой причине MySQL не поддерживает стандартную SQL-операцию
| | для конкатенации строк. Вместо этого необходимо применять функцию
CONCAT (). Поскольку CONCAT () принимает любое количество аргументов, пре-
образовать все операции | | очень легко.
• Использование COUNT (DISTINCT список), где список содержит более одного
элемента.
• Все сравнения строк по умолчанию чувствительны к регистру, а порядок сор-
тировки определяется текущим выбранным набором символов (по умолчанию
ISO-8859-1 Latin 1). Если это не подходит, потребуется объявить столбец с ат-
рибутом BINARY либо воспользоваться приведением к BINARY, что заставит вы-
полнять сравнение и сортировку в соответствии с кодами символов, а не в лек-
сикографическом порядке.
• Операция % является синонимом функции MOD (). То есть, выражение N % м эк-
вивалентно MOD(N, M). '%' поддерживается для удобства программистов на
языке С и достижения совместимости с СУБД PostgresSQL.
• Операции =, о , <=, <, >=, >, « , » , <=>, AND, OR и LIKE могут применяться для
сравнения столбцов слева от конструкции FROM в операторах SELECT, например:
mysql> SELECT coll=l AND col2=2 FROM имя^таблицы;
• Функция LASTINSERTIDO возвращает самое последнее значение
AUTO_INCREMENT.
• LIKE можно применять к числовым столбцам.
• Расширенные операции обработки регулярных выражений REGEXP и NOT
REGEXP.
1.8. Соответствие стандартам MySQL 61

• Функции CONCAT () и CHAR () принимают один и более аргументов.


• Ф у н к ц и и B I T _ C 0 U N T ( ) , CASE, E L T ( ) , F R O M _ D A Y S ( ) , FORMAT ( ) , I F ( ) , PASSWORD ( ) ,
ENCRYPT ( ) , MD5 ( ) , ENCODE ( ) , DECODE ( ) , PERIOD_ADD ( ) , P E R I O D _ D I F F ( ) , TO_DAYS ( )
И WEEKDAY().
• Применение TRIM() для усечения подстрок. Стандартный язык SQL поддер-
живает только удаление последовательностей одинаковых символов.
• Возможность в конструкции GROUP BY обращаться к функциям STD(),
BIT_OR(), BIT_AND(), BIT_XOR() И GROUP_CONCAT().
Для ознакомления с перечнем новых расширений, которые планируется добавить в
сервер MySQL, а также с их приоритетностью, просмотрите список "TODO" по адресу
http://dev.mysql.com/doc/mysql/en/TODO.html. В настоящем руководстве представле-
на последняя на данный момент версия списка "TODO". См. также раздел 1.6.

1.8.5. Отличия MySQL от стандартного SQL


Мы стараемся, чтобы MySQL в основном следовал требованиям стандартов ANSI
SQL и ODBC SQL, но в приведенных ниже случаях некоторые операции MySQL выпол-
няет иначе:
• В столбцах типа VARCHAR завершающие пробелы удаляются при сохранении зна-
чения (см. раздел 1.8.7).
• В некоторых случаях столбцы типа CHAR скрыто преобразуются в VARCHAR, когда
определяется либо изменяется структура таблицы.
• Привилегии для таблицы при удалении таблицы автоматически не удаляются. Для
этого необходимо явно вызвать оператор REVOKE.

1.8.5.1. Подзапросы
MySQL 4.1 поддерживает подзапросы и вторичные таблицы. Подзапрос - это опера-
тор SELECT, вложенный в другой оператор. Вторичная таблица (неименованное пред-
ставление) - это подзапрос в конструкции FROM другого оператора. Для более старых
версий MySQL большинство подзапросов могут быть переписаны в виде объединений
или с использованием других методов.

1.8.5.2. Оператор SELECT INTO TABLE


В сервере MySQL не реализована поддержка следующего расширения SQL от
Sybase: SELECT... INTO TABLE... Вместо этого MySQL поддерживает стандартный SQL-
синтаксис INSERT INTO... SELECT..., который в основном делает то же самое.
INSERT INTO tbl_temp2 (fld_id)
SELECT tbl_templ.fld_order_id
FROM tbl_templ WHERE tbl_templ.fld_order_id > 100;
В качестве альтернативы можно воспользоваться SELECT INTO OUTFILE... или
CREATE TABLE SELECT...
Начиная с версии 5.0, MySQL поддерживает SELECT.. .INTO с пользовательскими пе-
ременными.
62 Глава 1. Общая информация

1.8.5.3. Транзакции и атомарные операции


Сервер MySQL (старшие выпуски версий 3.23 и все версии, начиная с 4.0) поддержи-
вает транзакции в механизмах хранения innoDB и BDB. innoDB обеспечивает полную со-
вместимость с ACID.
Остальные нетранзакционные механизмы хранения MySQL (такие, как My ISAM) сле-
дуют различным парадигмам обеспечения целостности данных, которые называются
"атомарными операциями". В терминологии транзакций таблицы My ISAM всегда работа-
ют в режиме AUTOCOMMIT=1. Атомарные операции часто предлагают сопоставимую цело-
стность с более высокой производительностью.
Поскольку сервер MySQL поддерживает обе парадигмы, вы сами решаете, будут ли
ваши приложения лучше работать со скоростью атомарных операций или с использова-
нием средств управления транзакциями. Этот выбор осуществляется на уровне таблиц.
Как упоминалось ранее, различия в работе между транзакционными и нетранзакци-
онными таблицами отражаются в основном на производительности. Транзакционные
таблицы требуют значительно больших затрат памяти, дискового пространства и на-
грузки на центральный процессор. С другой стороны, транзакционные таблицы, подоб-
ные InnoDB, также предлагают много существенных дополнительных возможностей.
Модульная архитектура сервера MySQL допускает одновременное использование раз-
ных механизмов хранения для удовлетворения различным требованиям и достижения
оптимальной производительности во всех ситуациях.
Но как использовать средства сервера MySQL для поддержки строгих требований
целостности данных даже на нетранзакционных таблицах My ISAM, и как эти средства
сравнить с работой с транзакционными таблицами?
1. Если ваше приложение написано таким образом, что оно зависит от возможности
вызывать ROLLBACK вместо COMMIT в критических ситуациях, транзакции более
удобны. Транзакции также гарантируют, что незавершенные обновления или ре-
зультаты сбоев не будут записаны в базу данных. Сервер имеет возможность вы-
полнить автоматический откат и сохранить базу данных. Если же вы применяете
нетранзакционные таблицы, сервер MySQL почти во всех случаях предоставляет
вам возможность разрешить потенциальные проблемы, включив простые провер-
ки перед обновлением или, запуская простые сценарии, которые проверяют базу
данных на непротиворечивость и автоматически вносят исправления либо выдают
предупреждения, если обнаружены какие-то противоречия. Стоит отметить, что
даже просто включая протоколирование работы MySQL или добавляя дополни-
тельный протокол, вы можете нормально исправить таблицы без потери целост-
ности.
2. В большинстве случаев критические транзакционные обновления могут быть пе-
реписаны как атомарные операции. Вообще говоря, все проблемы целостности,
которые решают транзакции, могут быть предотвращены блокировкой таблиц
LOCK TABLE или атомарными обновлениями, гарантирующими, что вы никогда не
будете автоматически прерваны сервером, что является общей проблемой тран-
закционных систем управления базами данных.
3. Даже транзакционные системы могут терять данные, если сервер отключается.
Разница между системами состоит только в том, насколько мал промежуток вре-
мени, в течение которого возможна потеря данных. Нет систем, безопасных на
100%, а есть только "достаточно безопасные". Даже СУБД Oracle, имеющая репу-
1.8. Соответствие стандартам MySQL 63

тацию наиболее безопасной из транзакционных систем, периодически сообщает


об утере данных в ситуациях подобного рода.
Для безопасной работы с сервером MySQL, независимо от того используются или
нет транзакционные таблицы, нужно иметь резервные копии и держать включен-
ным бинарное протоколирование. В этом случае вы сможете восстановить данные
после любой ситуации, в которую можно попасть, имея дело с другими система-
ми. Вообще говоря, располагать актуальными резервными копиями полезно при
работе с любой СУБД.
Транзакционная парадигма обладает своими преимуществами и недостатками. Мно-
гие пользователи и разработчики приложений зависят от того, насколько просто можно
написать код, моделирующий систему, для которой прерывание работы возможно или
необходимо. Однако, даже если вы новичок в парадигме атомарных операций, либо
лучше знакомы с транзакционной моделью, согласитесь, что выигрыш в производитель-
ности в 3-5 раз, который дает применение нетранзакционных таблиц по сравнению с
наиболее быстрыми и оптимизированными транзакционными, весьма существенен.
В ситуациях, когда целостность данных чрезвычайно важна, сервер MySQL демонст-
рирует надежность уровня транзакционных систем даже при работе с нетранзакционны-
ми таблицами. Если выполняется блокировка таблицы командой LOCK TABLE, все обнов-
ления приостанавливаются до тех пор, пока не выполнятся все проверки целостности.
Если применяется блокировка READ LOCAL (в отличие от блокировки записи) для табли-
цы, допускающей параллельную вставку в конец, чтение разрешено, равно как и вставка
другими клиентами. Вновь добавленные записи не будут видимы клиентом, установив-
шим блокировку чтения, до тех пор, пока он не снимет блокировку. Применяя INSERT
DELAYED, вы можете вставлять записи в локальную очередь до тех пор, пока не будет
снята блокировка, не заставляя клиента ожидать завершения операции вставки.
Слово "атомарный" в том смысле, в каком мы его понимаем, не несет в себе ничего
сверхъестественного. Оно означает только то, что вы можете быть уверены, что пока
специфическое обновление идет, никакой другой пользователь не может взаимодейство-
вать с ним, и поэтому не будет никакого автоматического отката (что может случиться с
транзакционными таблицами, если вы не проявите достаточную осторожность). Сервер
MySQL также гарантирует, что не будет никаких недействительных результатов чтения
(dirty read).
Ниже перечислены некоторые приемы работы с нетранзакционными таблицами.
• Циклы, которые нуждаются в транзакциях, обычно могут быть закодированы с
помощью LOCK TABLES; необходимости иметь дело с курсорами для обновления
записей на лету нет.
• Для того чтобы избежать использования ROLLBACK, можно прибегнуть к следую-
щей стратегии:
1. Используйте LOCK TABLES для блокировки всех таблиц, к которым нужен доступ.
2. Проверяйте все условия, которые должны быть истинными до начала обнов-
лений.
3. Выполняйте обновления только если все в порядке.
4. Используйте UNLOCK TABLES для разблокирования таблиц.
Обычно это значительно более быстрый метод, чем применение транзакций с
возможными откатами, хотя и не всегда. Единственная ситуация, когда это реше-
64 Глава 1. Общая информация

ние не удачно, это если кто-то прервет поток приложения во время обновления. В
таком случае все блокировки будут сняты, но часть обновлений останется невы-
полненной.
• Можно также использовать функции для обновления записей за одну операцию.
Можно получить весьма эффективные приложения, применяя следующую технику:
• Модифицировать столбцы в соответствии с их текущими значениями.
• Обновлять только те столбцы, которые изменились.
Например, когда выполняется обновление информации о заказчиках, мы обновля-
ем только те данные, что изменились, либо данные, зависящие от измененных
данных, сравнив их новые значения с исходными. Проверка измененных данных
делается в конструкции WHERE оператора UPDATE. Если в результате запись не из-
менилась, потребуется выдать клиенту сообщение наподобие: "Некоторые из из-
меняемых вами данных изменены другим пользователем". Затем следует отобра-
зить старую и новую версии записи о клиенте, чтобы пользователь решил, какую
из них принять.
Это обеспечивает механизм, подобный блокировке столбца, но на самом деле да-
же лучше, потому что мы обновляем только некоторые из столбцов, используя
новые значения, зависящие от их текущих значений. Это означает, что типовые
операторы UPDATE должны выглядеть, как показано ниже:
UPDATE tablename SET pay_back=pay_back+125;
UPDATE customer
SET
customer_date='current_date',
address='new address',
phone='new phone',
money_owed_to_us=money_owed_to_us-125
WHERE
customer_id=id AND address='old address' AND phone='old phone';
Такой подход весьма эффективен и работает, даже если другой клиент изменяет
значения столбцов pay_back и money_owed_to_us.
• Во многих случаях пользователи хотят применять LOCK TABLES и/или ROLLBACK
для целей управления уникальными идентификаторами. Это также можно обра-
ботать гораздо более эффективно без блокировок и откатов, используя столбцы
AUTO_INCREMENT И либо SQL-фунКЦИЮ LAST_INSERT_ID(), либо функцию С API С
именем mysql_insert_id ().
Обычно можно написать код, обслуживающий ситуации, когда требуется блоки-
ровка уровня строки. В некоторых ситуациях это действительно необходимо, и
таблицы innoDB поддерживают такие блокировки. Для таблиц My ISAM можно вос-
пользоваться столбцами-флагами и поступить примерно так:
UPDATE имя_таблицы SET row_flag = 1 WHERE id = ID;
MySQL вернет 1 в качестве количества обновленных записей, если строка найде-
на и rowf lag не был равен 1 в исходной строке.
Можете думать об этом, как если бы сервер MySQL изменил предыдущий запрос
на такой:
UPDATE имя_таблицы SET row_flag = 1 WHERE id = ID AND row_flag <> 1;
1.8. Соответствие стандартам MySQL 65

1.8.5.4. Хранимые процедуры и триггеры


Хранимые процедуры реализованы в MySQL 5.O.
Триггеры запланированы к реализации в версии 5.1. Триггер - это разновидность хра-
нимой процедуры, которая вызывается при наступлении какого-то события. Например,
можно написать процедуру, которая отрабатывает каждый раз, когда запись удаляется из
транзакционной таблицы, и эта процедура автоматически удаляет соответствующего за-
казчика из таблицы заказчиков, когда все его финансовые транзакции удалены.

1.8.5.5. Внешние ключи


В сервере MySQL 3.23.44 и последующих версий механизм хранения InnoDB поддер-
живает проверку ограничений на внешние ключи, включая CASCADING, ON DELETE и ON
UPDATE.
Для других механизмов хранения MySQL анализирует синтаксис FOREIGN KEY в опе-
раторе CREATE TABLE, но не использует и не хранит его. В будущих реализациях плани-
руется сохранять эту информацию в файле спецификаций таблиц, чтобы она могла быть
извлечена с помощью mysqldump и через ODBC. На более поздней стадии ограничения
внешних ключей будут реализованы и для таблиц My ISAM.
Применение внешних ключей дает разработчикам баз данных некоторые преимущества:
• Если предположить, что отношения между таблицами спроектированы правиль-
но, ограничения внешних ключей значительно затрудняют программистам воз-
можность внести в базу данных какую-либо противоречивую информацию.
• Централизованная проверка ограничений со стороны сервера делает излишней эту
проверку со стороны приложения. Это исключает вероятность того, что некото-
рые приложения могут ее выполнять, а некоторые - нет.
• Применением каскадных обновлений и удалений может существенно упростить
код приложений.
• Правильно спроектированные внешние ключи упрощают документирование от-
ношений между таблицами.
Однако следует помнить, что эти выгоды достигаются за счет большей нагрузки на
сервер баз данных, которому приходится выполнять все проверки. Это приводит к неко-
торому снижению производительности, что для ряда приложений может оказаться на-
столько нежелательным, что лучше обойтись без этого вообще. (Некоторые важные
коммерческие программы по этой причине имеют встроенную проверку логики внешних
ключей на уровне приложения.)
MySQL дает возможность разработчикам выбирать требуемый подход. Если вам не
нужны внешние ключи, и вы хотите избежать лишней нагрузки, связанной с проверками
ссылочной целостности, вы можете выбрать другой тип таблиц, такой как My ISAM. На-
пример, механизм хранения My ISAM обеспечивает очень высокую производительность
для приложений, которые выполняют только операции INSERT и SELECT, поскольку
вставки могут выполняться одновременно с выборками.
Если вы предпочитаете обойтись без преимуществ проверки ссылочной целостности,
вам следует иметь в виду следующее:
• При отсутствии проверки отношений внешних ключей со стороны сервера этим
должно заниматься само приложение. Например, придется заботиться о вставке
записей в таблицы в правильном порядке, избегая появления висячих дочерних
66 Глава 1. Общая информация

записей. Приложение также должно быть готовым к восстановлению после оши-


бок, связанных с прерыванием операций массовой вставки записей.
• Если приложению требуется только ссылочная целостность типа ON DELETE, сле-
дует отметить, что в MySQL 4.0 имеется возможность выполнять многотабличные
операции DELETE для удаления записей из многих таблиц одним оператором.
• Обходной путь, позволяющий компенсировать отсутствие ON DELETE, заключается
в том, чтобы добавить соответствующие дополнительные операторы DELETE в
приложение для удаления записей из таблиц, имеющих внешние ключи. На прак-
тике часто это работает так же быстро, как и автоматические внешние ключи, но
при этом значительно более переносимо.
Не забывайте, что применение внешних ключей иногда порождает проблемы:
• Поддержка внешних ключей применима ко многим случаям, когда нужно обеспе-
чить ссылочную целостность, но это не отменяет необходимости очень тщатель-
ного проектирования отношения ключей, чтобы избегать циклических зависимо-
стей или некорректных комбинаций каскадного удаления.
• Не столь уж необычна ситуация, когда администратор баз данных создает такую
топологию отношений между таблицами, которая затрудняет восстановление от-
дельных таблиц из резервной копии. (MySQL смягчает сложность ситуаций по-
добного рода, позволяя временно отключать проверки внешних ключей на время
загрузки данных в таблицы, зависящие от других таблиц. В MySQL 4.1.1 утилита
mysqldump генерирует файлы дампа, которые это делают автоматически при за-
грузке.)
Следует помнить, что внешние ключи в SQL применяются для проверки и поддержа-
ния ссылочной целостности, но не для объединения таблиц. Если вам нужен результат
запроса к множеству таблиц от одного оператора SELECT, вы делаете это за счет описа-
ния объединения между ними:
SELECT * FROM tl, t2 WHERE tl.id = t2.id;
Синтаксис FOREIGN KEY без ON DELETE... часто применяется в ODBC-приложениях
для автоматической генерации конструкций WHERE.

1.8.5.6. Представления
Представления в настоящее время реализованы и появятся в версии 5.0 сервера
MySQL. Неименованные представления {вторичные таблицы, подзапросы в конструк-
ции FROM оператора SELECT) уже реализованы в версии 4.1.
Исторически сложилось так, что сервер MySQL больше всего использовался в при-
ложениях и Web-системах, где разработчик имел полный доступ к используемой базе
данных. Однако ситуация постепенно менялась, и теперь мы обнаружили, что все воз-
растающее число пользователей считают представления очень важным и полезным
средством.
Представления применяются для того, чтобы предоставить пользователям доступ к
группе таблиц таким образом, как будто это одна таблица и тем самым ограничить дос-
туп к ним. Представления также можно использовать для ограничения доступа к стро-
кам таблицы (выделяя, таким образом, подмножество записей). Для ограничения досту-
па к столбцам представления не нужны, поскольку сервер MySQL обладает развитой
системой привилегий.
1.8. Соответствие стандартам MySQL 67

Многие СУБД не разрешают выполнять операции обновления представлений. Вме-


сто этого необходимо обновлять отдельные таблицы. При разработке механизма под-
держки представлений в MySQL нашей целью было, оставаясь, насколько возможно, в
рамках стандарта SQL, достичь полной совместимости с шестым правилом Кодда для
реляционных баз данных. Все представления, теоретически обновляемые, должны быть
обновляемы на практике.
1.8.5.7.'--' как начало комментария
В ряде других СУБД ' — ' используется для обозначения начала комментария. Сервер
MySQL в качестве начального символа комментария использует '#'. Также поддержи-
ваются комментарии в стиле языка С: /* пример комментария */.
Сервер MySQL 3.23.3 и более поздние версии поддерживают комментарии, начи-
нающиеся с '—', предполагая, что за комментарием следует пробел (или управляющий
символ вроде перевода строки). Требование, касающееся пробелов, предотвращает про-
блемы с автоматически сгенерированными SQL-запросами, которые используют что-
нибудь наподобие показанного ниже кода, где вместо !payment! автоматически под-
ставляется значение оплаты:
UPDATE account SET credit=credit-'payment!
Подумайте, что случится, если значение оплаты будет отрицательным, например, -1:
UPDATE.account SET credit=credit—1
credit—1 - вполне корректное выражение на языке SQL, но если — интерпретиру-
ется как начало комментария, то часть выражения после этого фрагмента теряется. В
результате получаем оператор, имеющий совершенно другой смысл, чем ожидалось:
UPDATE account SET credit=credit
Он не выполняет никакого обновления вообще! Это иллюстрирует то обстоятельст-
во, что разрешение использовать в качестве начала комментария '--' чревато довольно-
таки неприятными последствиями.
Используя реализацию метода задания комментариев, поддерживаемую в MySQL
3.23.3 и последующих версиях, получаем безопасное выражение credit—1.
Другое безопасная возможность состоит в том, что интерпретатор командной строки
mysql удаляет строки, начинающиеся с ' - - ' .
Приведенная далее информация справедлива, только если вы работаете с MySQL
версий, предшествующих 3.23.3.
Если у вас есть SQL-программа в текстовом файле, которая включает комментарии,
начинающиеся с *—', вам придется с помощью утилита replace заменить их на коммен-
тарии с символом '#':
shell> replace " —" " #" < text-file-with-funny-comments.sql \
| mysql имя_базы_данных
вместо обычного:
shell> mysql имя_базы_данных < text-file-with-funny-comments.sql
Можно также отредактировать командный файл на месте, заменив ' — ' на '#':
shell> replace " —" " #" — text-file-with-funny-comments.sql
Вернуться к исходному варианту можно следующим образом:
shell> replace " #" " —" — text-file-with-funny-comments.sql
68 Глава 1. Общая информация

1.8.6. Как MySQL работает с ограничениями


MySQL позволяет работать как с транзакционными таблицами, для которых возмо-
жен откат, так и с нетранзакционными, для которых откат не предусмотрен, поэтому
работа с ограничениями (constraints) в MySQL несколько отличается от того, как это де-
лается в других СУБД.
Нам приходится иметь дело с ситуацией, когда нужно обновить множество строк в
нетранзакционной таблице, причем нет возможности выполнить откат при возникнове-
нии ошибки.
Базовая философия состоит в том, чтобы попытаться сгенерировать ошибку для все-
го, что можно обнаружить во время компиляции, но попытаться восстановиться после
любой ошибки, возникшей во время выполнения. Мы достигаем этого в большинстве
случаев, но пока еще не во всех (см. раздел 1.6.4).
Выбор, который стоит перед MySQL сводится к тому, что в случае возникновения
ошибки необходимо остановить выполнение оператора на полпути или восстановить
данные настолько хорошо, насколько возможно, и продолжать работу.
В последующих разделах описано, что происходит в этих случаях с различными ти-
пами ограничений.

1.8.6.1. Ограничение PRIMARY KEY/UNIQUE


Нормально, если генерируется ошибка при попытке вставить или обновить запись,
которая приводит к нарушению ограничений первичного ключа, внешнего ключа или
уникального ключа. Если используется транзакционный механизм хранения, подобный
innoDB, MySQL автоматически выполнит откат транзакции. Если же применяется не-
транзакционный механизм хранения, MySQL остановится на некорректной записи и ос-
тавит все оставшиеся записи неизмененными.
Чтобы облегчить жизнь, MySQL поддерживает ключевое слово IGNORE для большин-
ства команд, которые могут привести к нарушению ключей (например, INSERT IGNORE
или UPDATE IGNORE). В этих случаях MySQL просто игнорирует любые нарушения огра-
ничений ключей и продолжает обрабатывать остальные строки. Информация о том, что
предпринял MySQL, доступна через функцию mysql_info() API-интерфейса С. В
MySQL 4.1 и последующих версиях можно также воспользоваться командой SHOW
WARNINGS.
Стоит напомнить, что на данный момент внешние ключи поддерживают только таб-
лицы InnoDB. Реализация внешних ключей для таблиц My ISAM запланирована в версии
MySQL 5.1.

1.8.6.2. Ограничения NOT NULL и значения DEFAULT


Чтобы обеспечить простое управление нетранзакционными таблицами, все столбцы
таблиц в MySQL имеют значения по умолчанию.
Если вы вставляете "неправильное" значение в столбец, такое как NULL в столбец,
объявленный как NOT NULL, или же слишком большое значение в числовой столбец,
MySQL установит его значение в "лучшее из возможных" вместо того, чтобы выдавать
ошибку:
• Если вы попытаетесь сохранить в числовом столбце значение, выходящее за пре-
делы допустимого диапазона, сервер MySQL вставит вместо него ноль, мини-
мально возможное либо максимально возможное значение для этого столбца.
1.8. Соответствие стандартам MySQL 69

• В строковом столбце сервер MySQL сохранит либо пустую строку, либо самую
длинную, которая может поместиться в данный столбец.
• Если вы попытаетесь вставить строку, начинающуюся не с цифры, в числовой
столбец, MySQL запишет туда 0.
• Если попытаться вставить значение NULL в столбец, не допускающий значений
NULL, MySQL вставит вместо этого 0 в числовой столбец и пустую строку - в
символьный. (Однако такое поведение при вставке одиночных записей может
быть изменено, если скомпилировать сервер MySQL с опцией компиляции
-DONT_USE_DEFAULT_FIELDS.) Это заставит операторы INSERT генерировать ошиб-
ки, если только вы явно не зададите значения для всех столбцов, которые требуют
значений NOT NULL.
• MySQL позволит сохранить некоторые неправильные значения даты в столбцы
типа DATE и DATETIME (например '2000-02-31' или '2000-02-00'). Идея состоит в
том, что проверка корректности дат не является обязанностью сервера SQL. Если
MySQL может сохранять значение даты и извлекать точно такое значение, он со-
храняет его таким, как получил. Если дата абсолютно неправильная (за пределами
возможностей сервера сохранить ее), то вместо нее сохраняется специальное зна-
чение '0000-00-00'.
Причина существования изложенных правил заключается в том, что мы не можем
проверить эти условия до тех пор, пока не начнется выполнение запроса. Мы не можем
выполнить откат изменений, если сталкиваемся с проблемой после того, как несколько
строк уже обновлены, поскольку данный тип таблиц может не поддерживать транзак-
ции. Выбор в пользу прерывания выполнения оператора представляется неудачным - в
этом случае получается, что обновление выполнено наполовину, что приводит к наи-
худшему сценарию. В этом случае предпочтительнее сделать "лучшее из возможного" и
затем продолжить, как будто ничего не произошло.
Это означает, что не стоит полагаться на MySQL в смысле проверки корректности
данных столбцов. Вместо этого приложение само должно заботиться о том, чтобы от-
правлять серверу MySQL только правильные данные.
В MySQL 5.0 мы планируем провести улучшения, выдавая предупреждения, когда
происходит автоматическое преобразование столбцов, плюс опцию, позволяющую отка-
тить оператор, который пытается выполнить запрещенное присваивание данных до тех
пор, пока используются только транзакционные таблицы.

1.8.6.3. Ограничения ENUM и SET


В MySQL 4.x ENUM не является настоящим ограничением, а просто наиболее эффек-
тивным способом определения столбцов, которые могут содержать значения только из
заданного набора возможных значений.
Если вы вставляете некорректное значение в столбец типа ENUM, оно устанавливается
в зарезервированное перечислимое значение 0, которое отображается как пустая строка
в строчном контексте.
При попытке вставки некорректного значения в столбец типа SET это значение игно-
рируется. Например, если столбец может содержать значения ' а ' , ' Ь ' и ' с ' , попытка
сохранить в столбце значения ' а, х, Ь, у' приведет к сохранению ' a, b ' .
70 Глава 1. Общая информация

1.8.7. Известные ошибки и недостатки дизайна MySQL


1.8.7.1. Ошибки в версии 3.23, исправленные в более
поздних версиях MySQL
Перечисленные ниже известные ошибки не были исправлены в версии 3.23, посколь-
ку их исправление привело бы к изменению большой части кода, что могло, в свою оче-
редь, вызвать появление других, даже намного худших ошибок. Эти ошибки классифи-
цируются как "не критические" или "терпимые".
• Можно возникнуть взаимная блокировка, если использовать LOCK TABLE для бло-
кировки нескольких таблиц и затем в том же соединении удалить одну из них
оператором DROP TABLE в то время, когда другой поток пытается ее заблокиро-
вать. (Для устранения взаимной блокировки можно с помощью команды KILL за-
вершить любой из участвующих в ней потоков.) Эта проблема была решена в
MySQL 4.0.12.
• SELECT МАХ {ключевой__столбец) FROM t l , t 2 , t 3 . . . , где одна из таблиц пуста, не
возвращает NULL, а возвращает максимальное значение столбца. Это исправлено в
MySQL 4.0.11.
• DELETE FROM таблица_Пеар без конструкции WHERE не работает на блокированной
НЕАР-таблице.

1.8.7.2. Ошибки в версии 4.0, исправленные в более поздних версиях


Перечисленные ниже известные ошибки не были исправлены в версии 4.0, поскольку
их исправление привело бы к изменению большой части кода, что могло, в свою оче-
редь, вызвать появление других, даже намного худших ошибок. Эти ошибки также клас-
сифицируются, как "не критические" или "терпимые".
• В UNION первый же оператор SELECT определяет свойства результирующих столб-
цов - тип, максимальную длину (max_length), возможность записи значений NULL.
Это было исправлено в MySQL 4.1.1 - значения свойств столбцов определяются
на основании строк из всех частей UNION.
• В операторе DELETE по нескольким таблицам невозможно обращаться к таблицам
по псевдонимам. Исправлено в MySQL 4.1.

1.8.7.3. Открытые ошибки и недостатки дизайна MySQL


Следующие проблемы уже известны и решение их имеет наивысший приоритет:
• Удаление ограничений FOREIGN KEY не работает на реплицированной копии, по-
скольку ограничение может иметь другое имя, чем в исходной базе.
• REPLACE (и LOAD DATA С опцией REPLACE) не вызывает ON DELETE CASCADE (каскад-
ного удаления).
• Невозможно смешивать UNION ALL и UNION DISTINCT в одном и том же запросе.
Если используется ALL для одного из UNION, это касается их всех.
• Если один пользователь запустил долго выполняемую транзакцию, а другой уда-
лил таблицу, которая обновлялась в этой транзакции, то существует небольшая
вероятность того, что в бинарный протокол попадет команда DROP TABLE, прежде
чем таблица будет задействована в транзакции. Мы планируем исправить это в
1.8. Соответствие стандартам MySQL 71

версии 5.0, заставив оператор DROP TABLE ожидать до тех пор, пока таблица ис-
пользуется хотя бы в одной транзакции.
• При вставке больших целочисленных значений (между 2 6 3 и 2 6 4 - 1) в десятичный
или строковый столбец, оно вставляется как отрицательное значение, поскольку
число оценивается в контексте целого со знаком. Мы планируем исправить это в
MySQL 4.1.
• FLUSH TABLES WITH READ LOCK не блокирует CREATE TABLE ИЛИ COMMIT, ЧТО может
привести к проблемам с позицией в бинарном протоколе при выполнении полного
резервного копирования таблиц и бинарного протокола.
• ANALYZE TABLE для таблиц BDB в некоторых случаях может приводить к тому, что
таблицы становятся недоступными до тех пор, пока не будет перезапущен mysqld.
Если это случается, в файл ошибок MySQL добавляется такая строка:
001207 22:07:56 bdb: log_flush: LSN past current end-of-log
• MySQL принимает скобки в конструкции FROM оператора SELECT, но молча игно-
рирует их. Причина того, что сообщения об ошибках не выдаются, состоит в том,
что очень многие клиенты при автоматической генерации запросов добавляют
скобки в конструкцию FROM, даже если в этом нет необходимости.
• Объединение многих RIGHT JOIN или комбинаций LEFT JOIN и RIGHT JOIN в од-
ном запросе могут не приводить к корректному результату, потому что MySQL
генерирует строки NULL для таблицы, следующей за LEFT JOIN или перед RIGHT
JOIN. Это будет исправлено в 5.0, одновременно мы добавим поддержку скобок в
предложение FROM.
• Не выполняйте ALTER TABLE для таблицы BDB, участвующей в многотабличных
транзакциях, до тех пор, пока все они не завершатся. (Транзакции могут быть
проигнорированы.)
• Команды ANALYZE TABLE, OPTIMIZE TABLE И REPAIR TABLE могут вызывать про-
блемы в таблицах, в которых используется INSERT DELAYED.
• Выполнение LOCK TABLE... и FLUSH TABLES... не гарантирует, что в таблице не
окажется наполовину завершенных транзакций.
• Таблицы BDB открываются несколько медленно. Если в базе данных есть много
таблиц BDB, потребуется немало времени, чтобы запустить клиент mysql с опцией
-А или выполнить rehash. В особенности это касается тех случаев, когда имеется
большой табличный кэш.
• Репликация использует протоколирование уровня запросов. Реплицируемая база
фиксирует выполняемые запросы в бинарном протоколе. Это очень быстрый,
компактный и эффективный метод протоколирования, который в большинстве
случаев работает превосходно. Однако, хотя нам и не известны такие случаи, су-
ществует теоретическая возможность того, что данные в исходной и целевой базе
окажутся разными, если запрос составлен таким образом, что модификация дан-
ных будет недетерминированной. Это остается на совести оптимизатора запросов.
(Вообще говоря, это очень плохая практика, даже за рамками темы репликации!).
Например:
• Операторы CREATE... SELECT или INSERT... SELECT, которые вставляют нуле-
вые или NULL-значения в столбцы AUTO INCREMENT.
72 Глава 1. Общая информация

• DELETE, если выполняется для таблицы, имеющей внешние ключи со свойст-


вом ON DELETE CASCADE.
• REPLACE. . .SELECT, INSERT IGNORE. . .SELECT, если ВО вставляемых данных
присутствуют дублированные ключи.
Если и только если все эти запросы не содержат конструкцию ORDER BY, гаранти-
руется детерминированный порядок.
Например, для INSERT... SELECT без ORDER BY, оператор SELECT может вернуть за-
писи в другом порядке (что может оказаться результатом того, что записи имеют
разный ранг и, следовательно, разные номера в столбцах AUTO_INCREMENT), в зави-
симости от того, как сработают оптимизаторы в исходной и целевой базах при ре-
пликации. Запросы могут быть оптимизированы различным образом в двух базах,
если:
• Файлы, используемые в запросах, не одинаковы. Например, OPTIMIZE TABLE
был запущен для исходных таблиц и не запускался для целевых (для исправ-
ления ЭТОГО, начиная С MySQL 4.1.1, OPTIMIZE TABLE, ANALYZE TABLE И REPAIR
TABLE записываются в бинарный протокол).
• Исходная и целевая таблицы обрабатываются разными механизмами хранения
(это возможно; например, вы можете использовать InnoDB в исходной репли-
цируемой базе и My ISAM - в целевой базе, если в ней нет дискового простран-
ства достаточного объема).
• Размер буферов разный (key__buf f e r _ s i z e и так далее).
• Исходная и целевая базы работают под управлением разных версий MySQL, и
коды оптимизаторов у них отличаются.
Эта проблема может также затронуть восстановление базы с использованием
mysqlbinlog|mysql.
Наилучший способ избежать этих проблем во всех случаях - добавлять конструк-
цию ORDER BY к подобным недетерминированным запросам, дабы гарантировать,
что строки сохраняются и модифицируются в одном и том же порядке. В будущих
версиях MySQL мы будем автоматически добавлять ORDER BY туда, где это необ-
ходимо.
Следующие проблемы известны и будут решены в надлежащее время:
• Имена файлов протоколов основаны на имени хоста (если только явно не указаны
при запуске). На сегодняшний день, если изменяется имя хоста, нужно использо-
вать опции наподобие —log-bin=старое_имя_хоста-Ып. Другой способ состоит в
том, чтобы просто переименовать старые файлы в соответствии с изменением
имени хоста.
• mysqlbinlog не удаляет временные файлы, которые остаются после выполнения
команды LOAD DATA INFILE.
• RENAME не работает на временных таблицах и таблицах, используемых в таблицах
MERGE.
• При использовании функции RPAD () в запросах, выполнение которых потребует
создания временных таблиц, во всех результирующих строках заключительные
пробелы будут удалены. Ниже показан пример такого запроса.
1.8. Соответствие стандартам MySQL 73

SELECT RPAD(tl.columnl, 50, ' ') AS f2, RPAD(t2.column2, 50, ' ') AS fl
FROM tablel as t l LEFT JOIN table2 AS t2 ON tl.record=t2.joinID
ORDER BY t2.record;
Вследствие этой ошибки вы не получите завершающих пробелов в результирую-
щих значениях. Эта проблема также относится ко всем остальным строковым
функциям, добавляющим пробелы справа.
Причиной является то, что НЕАР-таблицы, которые используются вначале для вре-
менных таблиц, не могут работать со столбцами типа VARCHAR.
Подобное поведение присуще всем версиям MySQL и будет исправлено в одном
из выпусков в рамках серии 4.1.
• Из-за способа хранения файла определений таблиц невозможно использовать
символ 255 (CHAR (255)) в именах таблиц, столбцов или перечислений. Исправле-
ние запланировано в версии 5.1, когда мы будем иметь новый формат файлов оп-
ределения таблиц.
• При использовании SET CHARACTER SET невозможно использовать переведенные
символы в именах баз данных, таблиц и столбцов.
• Невозможно использовать шаблонные символы '_', '%' вместе с ESCAPE в LIKE...
ESCAPE.

• Если есть столбец типа DECIMAL, в котором одно и то же число сохраняется в раз-
ных форматах (например, +01.00, 1.00, 01.00), то GROUP BY может рассматривать
такие значения как различные.
• Невозможно собрать сервер в другом каталоге при использовании потоков MIT-
pthreads. Поскольку для этого нужно изменять потоки MIT-pthreads, по всей ви-
димости, исправлять мы это не будем.
• Значения типа BLOB не могут "надежно" применяться в GROUP BY, ORDER BY или
DISTINCT. В этих случаях для сравнения значений BLOB используются только пер-
вые max_sort_length байт. Значение по умолчанию max_sort_length равно 1024
байта. Это может быть изменено во время запуска сервера. Чтобы обойти это ог-
раничение, в большинстве случаев можно применить подстроки, например:
SELECT DISTINCT LEFT {столбец_ЫоЬ, 2048) FROM имя_таблицы
• Вычислительные операции выполняются над типами BIGINT и DOUBLE (оба они
обычно имеют длину 64 байта). Какую точность вы получите, зависит от функ-
ции. Общее правило звучит так: поразрядные функции выполняются с точностью
BIGINT, IF и ELT () - с точностью BIGINT или DOUBLE, все остальные - с точностью
DOUBLE. Старайтесь избегать применения беззнаковых длинных значений, если
они могут оказаться длиной более 63 бит (9223372036854775807) во всех случаях,
кроме битовых полей. Версия MySQL 4.0 лучше справляется с BIGINT, чем версия
MySQL 3.23.
• У всех строковых столбцов, кроме BLOB и TEXT, при извлечении из базы автомати-
чески удаляются завершающие пробелы. Для типа CHAR это нормально. Ошибка
состоит в том, что столбцы VARCHAR обрабатываются точно так же.
• В одной таблице можно иметь не более 255 столбцов типа ENUM и SET.
74 Глава 1. Общая информация

• В MIN (), МАХ () и других агрегатных функциях в настоящее время столбцы типов
ENUM и SET сравниваются по их строковым значениям вместо того, чтобы делать
это по относительному положению строки в наборе.
• mysqld_saf e перенаправляет все сообщения от mysqld в журнал mysqld. Одна свя-
занная с этим проблема состоит в том, что если запустить mysqladmin refresh для
закрытия и повторного открытия журнала, стандартный поток вывода stdout и
стандартный поток ошибок stderr остаются перенаправленными в старый жур-
нал. Если —log применяется интенсивно, нужно отредактировать mysqld_safe,
чтобы он выводил протокол в имя_хоста.еп вместо имя_хоста.log. В этом слу-
чае можно легко использовать дисковое пространство, занятое старым журналом,
удалив его и запустив mysqladmin refresh.
• Оператор UPDATE обновляет столбцы слева направо. Если вы ссылаетесь на обнов-
ляемые столбцы, то получаете их новые значения вместо старых. Например, сле-
дующий оператор увеличит значение KEY на 2, а не на 1:
mysql> UPDATE имя_таблицы SET KEY=KEY+1,KEY=KEY+1;
• Можно обращаться к множеству временных таблиц в одном запросе, но нельзя
обращаться к одной и той же временной таблице более одного раза. Например,
приведенный ниже оператор не работает:
mysql> SELECT * FROM temp_table, temp_table AS t 2 ;
ERROR 1137: Can't reopen table: 'temp_table f
(ERROR 1137: Невозможно повторно открыть таблицу: 'temp table')
• Оптимизатор может обрабатывать DISTINCT по-разному, когда используются
"скрытые" столбцы в объединении и когда они не используются. Скрытые столб-
цы в объединении считаются частью результата (даже если они не показываются),
тогда как в нормальных запросах скрытые столбцы не участвуют в сравнениях
для DISTINCT. Возможно, мы исправим это в будущем, чтобы скрытые столбцы
никогда не участвовали в вычислении DISTINCT.
Ниже представлены соответствующие примеры:
SELECT DISTINCT mp3id FROM band_downloads
WHERE u s e r i d = 9 ORDER BY id DESC;

SELECT DISTINCT band_downloads.mp3id


FROM band_downloads,band_mp3
WHERE band_downloads.userid = 9
AND band_mp3.id = band_downloads.mp3id
ORDER BY band_downloads.id DESC;
Во втором случае сервер MySQL 3.23.x может выдать две идентичные строки в
результирующем наборе (поскольку значения скрытого столбца id у них различ-
ны). Отметим, что это случается с запросами, где в результате не выводятся
столбцы, участвующие в конструкции ORDER BY.
Поскольку MySQL позволяет работать с типами таблиц, для которых не поддер-
живаются транзакции, и поэтому невозможен откат, некоторые вещи работают
здесь несколько иначе, чем в других серверах SQL. Это связано только с тем, что-
бы гарантировать, что откат никогда не понадобится MySQL для выполнения
1.8. Соответствие стандартам MySQL 75

SQL-операторов. Иногда это может оказаться неудобным, потому что значения


столбцов должны проверяться самим приложением, но это дает существенный
выигрыш в скорости, так как позволяет MySQL выполнить оптимизацию, кото-
рую в противном случае было бы очень трудно реализовать.
Если вы устанавливаете некорректное значение столбца, MySQL вместо отката
пытается сохранить вместо него "наилучшее возможное" значение. Информацию
о том, как это происходит, можно найти в разделе 1.8.6.
• Если запускается PROCEDURE на запросе, возвратившем пустой результирующий
набор, в некоторых случаях PROCEDURE не трансформирует столбцы.
• При создании таблиц типа MERGE не выполняется проверка входящих в них таблиц
на предмет соответствия типов.
• Если вы используете ALTER TABLE вначале для добавления уникального индекса к
таблице, включенной в MERGE, а затем пытаетесь добавить нормальный индекс к
MERGE-таблице, порядок ключей будет разным, если существовал старый ключ,
который был не уникальным для таблицы. Это происходит ввиду того, что ALTER
TABLE помещает уникальные индексы перед нормальными индексами, чтобы как
можно раньше обнаружить дублированные ключи.
Далее перечислены известные ошибки в ранних версиях MySQL.
• В описанных ниже случаях может случиться аварийный отказ ядра.
• Обработчик отложенных вставок задерживает вставки в таблицу.
• LOCK TABLE С WRITE.
• FLUSH TABLE.
• До версии сервера MySQL 3.23.2 оператор UPDATE, обновляющий значения клю-
чей, упомянутых в конструкции WHERE, мог аварийно завершиться, поскольку
ключи используются для поиска записей, и одни и те же строки могли быть най-
дены по нескольку раз:
UPDATE имя_таблицы SET KEY=KEY+1 WHERE KEY > 100;
Обходной путь выглядит следующим образом:
UPDATE имя_таблицы SET KEY=KEY+1 WHERE KEY+0 > 100;
Это работает потому, что сервер MySQL не использует индексы для выражений в
КОНСТРУКЦИИ WHERE.

• До версии сервера MySQL 3.23 значения всех числовых типов трактовались как
числа с фиксированной запятой. Это означало, что нужно было явно указывать,
сколько десятичных знаков должно иметь поле с плавающей запятой. Все резуль-
таты возвращались с корректным количеством знаков.
2
Установка MySQL

в настоящей главе описаны вопросы, связанные с получением и установкой MySQL.


1. Определите, поддерживается ли ваша платформа. Следует иметь в виду, что
не все поддерживаемые системы одинаково хороши для выполнения MySQL. На
некоторых платформах MySQL работает значительно надежнее, чем на других
(см. раздел 2.1.1).
2. Выберите, какой дистрибутив устанавливать. Доступны несколько версий
MySQL и большинство доступны в нескольких форматах дистрибутива. Вы мо-
жете выбирать между заранее упакованным дистрибутивом, содержащим бинар-
ные (предварительно скомпилированные) программы, и дистрибутивом с исход-
ным кодом. В случае возникновения каких-то сомнений выбирайте бинарный ди-
стрибутив. Мы также предоставляем общий доступ к нашему текущему дереву
исходных текстов для тех, кто желает ознакомиться с последними разработками и
помочь нам тестировать новый код. Разобраться, какой версии и типу дистрибу-
тива отдать предпочтение, позволит информация, представленная в разделе 2.1.2.
3. Загрузите дистрибутив, который хотите установить. Список сайтов, откуда
можно получить MySQL, представлен в разделе 2.1.3. Целостность дистрибутива
можно проверить, воспользовавшись инструкциями из раздела 2.1.4.
4. Установите дистрибутив. Для установки MySQL из бинарного дистрибутива
воспользуйтесь инструкциями, предложенными в разделе 2.2. В установке MySQL
из дистрибутива с исходным кодом или из нашего текущего дерева исходных тек-
стов помогут инструкции в разделе 2.3. Если вы планируете обновить сущест-
вующую версию MySQL более новой версией, а не выполнять полную установку,
обратитесь в раздел 2.5, в котором представлена информация о процедуре обнов-
ления и о том, что необходимо сделать перед этим. Если вы столкнулись со слож-
ностями во время установки, в разделе 2.6 находятся рекомендации по решению
проблем для конкретных платформ.
5. Выполните необходимые настройки после установки. После установки MySQL
почитайте раздел 2.4, в котором содержится важная информация о том, как убе-
диться, что сервер MySQL работает правильно. Там же описано, как обеспечить
защиту начальных пользовательских учетных записей MySQL, которые не имеют
паролей до тех пор, пока вы не зададите их явно. Этот раздел касается установки
как из бинарного дистрибутива, так и из дистрибутива с исходным кодом.
6. Если вы хотите запустить сценарии, измеряющие производительность MySQL, в
системе должна присутствовать поддержка языка Perl (см. раздел 2.7).
2.1. Общие вопросы установки 77

2.1. Общие вопросы установки


Перед установкой MySQL потребуется выполнить следующие действия:
1. Определить, работает ли MySQL на вашей платформе.
2. Выбрать дистрибутив для установки.
3. Загрузить дистрибутив и проверить его на предмет целостности.
В настоящем разделе представлена информация, которая необходима для выполне-
ния этих шагов. После того, как они будут выполнены, можно приступать к собственно
установке выбранного дистрибутива, воспользовавшись дальнейшими инструкциями из
этой главы.

2.1.1. Операционные системы, поддерживаемые MySQL


Ниже перечислены операционные системы, под управлением которых может выпол-
няться MySQL.
Мы пользуемся GNU Autoconf, поэтому существует возможность переноса MySQL
на любую современную систему, в которой имеется компилятор C++ и работающая реа-
лизация потоков POSIX. (Поддержка потоков необходима для сервера. Для компиляции
только клиентского кода единственным условием является наличие компилятора C++.)
Мы используем и разрабатываем наше программное обеспечение преимущественно в
среде Linux (SuSE и Red Hat), FreeBSD и Sun Solaris (версий 8 и 9).
MySQL успешно компилируется на следующих комбинациях операционных систем и
пакетов поддержки потоков. Следует иметь в виду, что для многих операционных сис-
тем встроенная поддержка потоков присутствует только в их последних версиях.
• AIX 4.x, 5.x со встроенной поддержкой потоков. См. раздел 2.6.5.3.
• Amiga.
• BSDI 2.x с пакетом MIT-threads. См. раздел 2.6.4.5.
• BSDI 3.0, 3.1 и 4.x со встроенной поддержкой потоков. См. раздел 2.6.4.5.
• DEC UNIX 4.x со встроенной поддержкой потоков. См. раздел 2.6.5.5.
• FreeBSD 2.x с пакетом MIT-threads. См. раздел 2.6.4.1.
• FreeBSD 3.x и 4.x со встроенной поддержкой потоков. См. раздел 2.6.4.1.
• FreeBSD 4.x с поддержкой потоков LinuxThreads. См. раздел 2.6.4.1.
• HP-UX 10.20 с DCE-потоками из пакета MIT-threads. См. раздел 2.6.5.1.
• HP-UX 11.x со встроенной поддержкой потоков. См. раздел 2.6.5.2.
• Linux 2.0+ с Linux Threads 0.7.1+ или glibc 2.0.7+. См. раздел 2.6.1.
• Mac OS X. См. раздел 2.6.2.
• NetBSD 1.3/1.4 Intel и NetBSD 1.3 Alpha (требует наличия GNU make). См. раздел
2.6.4.2.
• Novell NetWare 6.0. См. раздел 2.2.4.
• OpenBSD > 2.5 со встроенной поддержкой потоков, OpenBSD < 2.5 с пакетом
MIT-threads. См. раздел 2.6.4.3.
• OS/2 Warp 3, FixPack 29 и OS/2 Warp 4, FixPack 4. См. раздел 2.6.6.
• SCO OpenServer с последним портом пакета FSU Pthreads. См. раздел 2.6.5.8.
78 Глава 2. Установка MySQL

• SCO UnixWare 7.1.x. См. раздел 2.6.5.9.


• SGI Irix 6.x со встроенной поддержкой потоков. См. раздел 2.6.5.7.
• Solaris 2.5 и выше со встроенной поддержкой потоков на SPARC и Intel. См. раз-
дел 2.6.3.
• SunOS 4.x с пакетом MIT-threads. См. раздел 2.6.3.
• Тш64 Unix.
• Windows 9x, Me, NT, 2000 и ХР. См. раздел 2.2.1.
Не на всех платформах MySQL работает одинаково хорошо. То, насколько подходит
определенная платформа для сильно загруженного, ответственного сервера MySQL, оп-
ределяется следующими факторами:
• Общая стабильность библиотеки поддержки потоков. Платформа может иметь
блестящую репутацию во всем остальном, но MySQL будет функционировать на
ней лишь настолько стабильно, насколько хороша библиотека поддержки пото-
ков, даже если все остальное работает великолепно.
• Способность ядра и библиотеки потоков использовать преимущества симметрич-
ных многопроцессорных систем (SMP). Другими словами, когда процесс порож-
дает поток, должна быть возможность выполнять эту поток на другом процессоре,
отличном от того, на котором работает оригинальный процесс.
• Способность ядра и библиотеки потоков выполнять множество потоков, устанавли-
вающих и сбрасывающих семафоры (mutex) через короткие частые промежутки без
чрезмерного переключения контекстов. Если реализация pthread_mutex_lock() бу-
дет отнимать слишком много процессорного времени, это катастрофическим об-
разом скажется на работе MySQL. Если не позаботиться об этой проблеме, то до-
бавление дополнительных процессоров только замедлит работу MySQL.
• Общая стабильность и производительность файловой системы.
• Если в базе данных будут храниться большие таблицы, важное значение имеет
способность файловой системы работать с большими файлами вообще и, к тому
же, работать с ними эффективно.
• Уровень знакомства с платформой специалистов компании MySQL AB. Если мы
знаем платформу хорошо, то можем выполнить специфическую для нее оптимиза-
цию и исправления во время компиляции. Мы также сможем дать советы по опти-
мальной настройке вашей системы для эффективного функционирования MySQL.
• Объем проведенного тестирования, выполненного нами для похожих конфигураций.
• Количество пользователей, успешно эксплуатирующих сервер MySQL на данной
платформе с похожими конфигурациями. Если оно велико, вероятность столкнуть-
ся со специфическими для данной платформы сюрпризами значительно меньше.
На основании перечисленных критериев наилучшей платформой для работы MySQL
на данный момент являются машины на базе процессоров х86, функционирующие под
управлением операционной системы SuSE Linux с ядром версии 2.4 и файловой систе-
мой ReiserFS (или аналогичной версией Linux), а также SPARC с операционной систе-
мой Solaris (2.7-9). Операционная система FreeBDS идет третьей в списке, но мы наде-
емся, что эта система войдет в категорию наилучших, как только будет усовершенство-
вана ее библиотека потоков. Мы также надеемся, что в какой-то момент мы сможем
включить в эту категорию и другие платформы, на которых MySQL сегодня компилиру-
2.1. Общие вопросы установки 79

ется и функционирует достаточно хорошо, однако не с такими показателями стабильно-


сти и производительности. Это потребует некоторых усилий с нашей стороны и тесного
взаимодействия с разработчиками операционных систем и библиотек компонентов, от
которых зависит MySQL. Если вы заинтересованы в усовершенствовании одного из этих
компонентов, занимаете должность, позволяющую повлиять на их разработку, и нуж-
даетесь в более подробных инструкциях относительно того, что нужно для того, чтобы
СУБД MySQL функционировала лучше, присылайте предложения по электронной почте
в группу рассылки MySQL i t e r n a l s (см. раздел 1.7.1.1).
Имейте в виду, что цель приведенных выше сравнений состоит не в том, чтобы ска-
зать, что одна операционная система (ОС) вообще лучше или хуже другой. Речь идет
только о выборе ОС для специфической цели - нормальной работы MySQL. Памятуя об
этом, результат сравнения будет другим, если учитывать большее число факторов. В
некоторых случаях причиной того, что одна ОС оказывается лучше другой, может быть
просто то обстоятельство, что у нас есть возможность приложить большие усилия для
тестирования и оптимизации нашего продукта на конкретной платформе. Здесь мы про-
сто делимся своим опытом, чтобы помочь вам принять решение, какую платформу ис-
пользовать для внедрения MySQL.

2.1.2. Выбор дистрибутива MySQL для установки


Во время подготовки к установке MySQL вы должны решить, какую версию выбрать
для использования. Разработка MySQL идет по нескольким сериям выпусков, и вы мо-
жете выбрать тот, который в большей степени удовлетворяет ваши требования. После
принятия решения о том, какую версию устанавливать, необходимо выбрать формат
дистрибутива. Выпуски доступны в бинарном формате или в виде исходного кода.

2.1.2.1. Выбор версии MySQL для установки


Первое решение, которое должно быть принято, связано с тем, какой выпуск нужен:
производственный (стабильный) или же находящийся в стадии разработки. В процессе
разработки MySQL сосуществуют несколько серий выпусков, пребывающих в разной
степени готовности:
• MySQL 5.0 - новейшая серия выпусков, находящаяся в стадии очень активной
разработки новых средств. Вплоть до последних дней она была доступна (в пред-
варительной форме) в репозитории исходных текстов BitKeeper. Ранний альфа-
выпуск был представлен для широкого тестирования.
• MySQL 4.1 - серия выпусков, находящаяся в разработке, к которой были добав-
лены важные новые средства. В настоящее время находится в стадии бета-
тестирования. Исходные тексты и бинарные дистрибутивы доступны для исполь-
зования и тестирования в системах разработки.
• MySQL 4.0 - текущая стабильная производственная серия выпусков. Новые вы-
пуски выходят с исправлениями ошибок. Никаких новых средств, которые спо-
собны нарушить стабильность кода, не добавляется.
• MySQL 3.23 - старая стабильная производственная серия выпусков. Данная серия
закрывается, поэтому новые выпуски издаются только для исправления критиче-
ских ошибок.
Мы не верим в полное замораживание работ, поскольку это означает также прекра-
щение исправлений ошибок и отказ от вещей, которые "должны быть сделаны". "Час-
80 Глава 2. Установка MySQL

тично замороженное состояние" означает, что мы можем внести какие-то мелкие изме-
нения, которые "почти наверняка не повлияют на то, что уже работает". Естественно,
исправления существенных ошибок в ранних версиях распространяются и на более
поздние серии продукта.
Как правило, если вы только впервые начинаете использовать MySQL или пытаетесь
перенести его в систему, для которой не существует бинарного дистрибутива, мы реко-
мендуем обратиться к серии производственных выпусков. В настоящее время это MySQL
4.0. Все выпуски MySQL, даже те, что относятся к сериям, пребывающим в разработке, до
выхода в свет обязательно проверяются с помощью тестов производительности.
Если вы эксплуатируете старую систему и хотите произвести обновление, но желае-
те, чтобы этот процесс прошел как можно более безболезненно, вам стоит обновить ее
до последнего выпуска той серии, к которой относится и ваша система (следует обра-
щать внимание на последнюю часть номера версии выпуска). Мы стараемся исправлять
только критические ошибки и вносить небольшие, относительно безопасные изменения
в эту версию.
Если вы хотите использовать новые средства, которые еще не входят в выпуски про-
изводственной серии, можете взять версию из серии, находящейся на стадии разработки.
Но при этом нужно помнить, что такие выпуски не настолько стабильны, как производ-
ственные.
Если вы хотите иметь самые последние исходные тексты, которые содержат все те-
кущие исправления, можете воспользоваться одним из наших репозиториев исходного
кода BitKeeper. Это еще не будет выпуском в полном смысле, однако даст предвари-
тельное представление о коде, на котором будут базироваться будущие выпуски.
Схема именования выпусков, принятая в MySQL, состоит из трех номеров и суффик-
са, например, mysql-4.1.2-alpha. Цифры в наименовании выпуска интерпретируются
следующим образом:
• Первое число (4) обозначает номер главной версии и также описывает формат
файлов. Все выпуски версии 4 используют один и тот же формат файлов.
• Второй номер (1) - это уровень выпуска. Взятые вместе номер главной версии и
уровень выпуска составляют номер серии выпуска.
• Третий номер (2) - это номер версии в серии выпусков. Эта цифра увеличивается
с каждым новым выпуском. Обычно вам нужна самая последняя версия из вы-
бранной серии.
С каждым небольшим обновлением последний номер версии увеличивается. Когда
добавляются существенные новые средства либо появляется малейшая несовместимость
с предыдущими версиями, увеличивается второй номер. Когда меняется формат файлов,
увеличивается первый номер.
Наименование выпуска включает также суффикс, указывающий на уровень его ста-
бильности. Имена выпусков в серии проходят через последовательность суффиксов, от-
ражающих рост уровня стабильности. Ниже описаны возможные суффиксы.
• alpha (альфа) означает, что выпуск содержит некоторую крупную часть нового кода,
который пока еще не был на 100% протестирован. Известные ошибки (обычно их еще
нет) должны быть документированы в разделе новостей (News) онлайнового спра-
вочного руководства по адресу http://dev.mysql.com/doc/mysql/en/News.html. В
большинстве альфа-выпусков появляются новые команды и расширения. Актив-
ная разработка, которая может включать изменения в основном коде, может осу-
2.1. Общие вопросы установки 81

ществляться в рамках альфа-выпуска, но все должно быть протестировано перед


его изданием. По этой причине не должно быть никаких известных ошибок в лю-
бом выпуске MySQL.
• beta (бета) означает, что весь новый код протестирован. Никаких существенных
новых средств, которые могут повредить старому коду, не добавляется. Не долж-
но существовать известных ошибок. Переход от альфа- к бета-выпуску происхо-
дит в случае, если документированных критических ошибок в альфа-версии не
появлялось в течение, минимум, месяца, а также не планируется добавление но-
вых средств, которые могли бы сделать любые старые команды ненадежными.
• gamma (гамма) - это бета-версия, которая находится в эксплуатации достаточно
долго и выглядит хорошо работающей. Были добавлены только минимальные ис-
правления. Это то, что многие другие компании называют выпуском.
• Если нет никакого суффикса, это означает, что версия эксплуатируется долго на
многих различных сайтах без сообщений об ошибках, за исключением тех, кото-
рые зависят от платформы. В таком выпуске исправляются только критические
ошибки. Это то, что мы называем производственным (стабильным) выпуском.
MySQL использует схему наименований, которая несколько отличается от принятой
в большинстве других продуктов. Вообще можно считать относительно безопасным ис-
пользование любой версии, которая существует много недель без замены на новую в
рамках той же серии выпусков.
Все выпуски MySQL проходят испытания на производительность и тестирование,
чтобы гарантировать их относительную безопасность в эксплуатации. Поскольку стан-
дартные тесты со временем расширяются, чтобы покрыть все ранее найденные ошибки,
наш тестовый набор становится со временем все лучше и лучше.
Все выпуски тестируются, как минимум, с помощью следующих средств:
• Внутренний тестовый набор. В каталоге mysql-test хранится обширный набор
тестовых случаев. Мы прогоняем эти тесты для каждого бинарного дистрибутива
сервера.
• Набор тестов производительности. Этот набор выполняет множество общих за-
просов. Данные тесты служат также для проверки того, что последняя серия оп-
тимизаций действительно делает код более быстрым (см. раздел 6.1.4).
• Тест crash-me. Этот тест пытается определить, какие средства СУБД поддержи-
вает и какие у нее есть возможности и ограничения (см. раздел 6.1.4).
Еще одно тестирование, которое мы проводим, - это эксплуатация новейшей версии
MySQL в нашей внутренней производственной среде, по крайней мере, на одной маши-
не. Мы располагаем более чем 100 Гбайт данных, которые и задействуем во время тес-
тирования.

2.1.2.2. Выбор формата дистрибутива


После выбора версии MySQL для установки потребуется решить, какой дистрибутив
использовать: бинарный или с исходным кодом. В большинстве случаев имеет смысл
выбирать бинарный дистрибутив, если только он существует для вашей платформы. Би-
нарные дистрибутивы доступны в собственных форматах для многих платформ, напри-
мер, в виде RPM-файлов для Linux или пакетных инсталляторов DMG для Mac OS X.
Дистрибутивы также имеются в форме Zip-архивов и сжатых файлов tar.
На выбор бинарного дистрибутива влияют следующие причины:
82 Глава 2. Установка MySQL

• Как правило, бинарные дистрибутивы проще устанавливать, чем исходные.


• Для того чтобы удовлетворить различные требования пользователей, мы предос-
тавляем две разных бинарных версии: одна скомпилирована с нетранзакционными
механизмами хранения (небольшая и быстрая), а другая сконфигурирована с наибо-
лее важными расширенными средствами, такими как безопасные транзакционные
таблицы. Обе версии скомпилированы из одного исходного дистрибутива. Все соб-
ственные клиенты MySQL могут подключаться к серверам обеих версий.
Расширенный бинарный дистрибутив MySQL отмечен суффиксом -шах и сконфи-
гурирован с теми де опциями, что mysqld-max. См. раздел 4.1.2.
Если вы хотите использовать RPM-модуль MySQL-Max, то сначала должны устано-
вить стандартный RPM-модуль MySQL-server.
Существуют и причины, по которым, возможно, лучше устанавливать MySQL с ис-
ходного дистрибутива:
• Требуется установить MySQL в некотором определенном окружении. Стандарт-
ные бинарные дистрибутивы готовы к запуску в любом месте, но вам может по-
надобиться большая гибкость в размещении компонентов MySQL там, где вы хо-
тите.
• Требуется сконфигурировать mysqld с некоторыми дополнительными средствами,
которые не включены в состав стандартных бинарных дистрибутивов. Ниже пе-
речислены некоторые общие дополнительные опции, которыми вы, возможно,
воспользуетесь:
--with-innodb (опция по умолчанию для MySQL 4.0 и выше)
--with-berkleydb (доступна не на всех платформах)
—with-raid
—with-libwrap
—with-names-z-libs (это сделано в некоторых бинарных дистрибутивах)
—with-debug[=full]
• Требуется настроить mysqld без некоторых средств, которые входят в состав
стандартных бинарных дистрибутивов. Например, дистрибутивы обычно компи-
лируются с поддержкой всех символьных наборов. Если вам нужен более ком-
пактный сервер MySQL, вы можете перекомпилировать его для работы только с
необходимым набором символов.
• У вас есть специальный компилятор (такой, например, как рдсс), либо вы хотите
использовать опции компилятора, которые позволяют получить лучше оптимизи-
рованный для вашего процессора код. Бинарные дистрибутивы скомпилированы с
опциями, которые позволяют им работать на различных процессорах из одного
семейства.
• Вы хотите использовать самые последние исходные тексты из нашего репозито-
рия BitKeeper, чтобы получить код со всеми последними исправлениями ошибок.
Например, если вы обнаружили ошибку и сообщили о ней группе разработчиков
MySQL, ее исправление будет внесено в репозиторий исходных текстов, и вы
сможете получить его оттуда. Исправление ошибок не включается в выпуск до
его официального выхода.
2.1. Общие вопросы установки 83

• Вы хотите изучить (или изменить) исходный код MySQL на С и C++. Для этой
цели потребуется получить исходный дистрибутив, поскольку исходный код - это
первичное и наиболее исчерпывающее руководство.
• Исходные дистрибутивы содержат больше тестов и примеров, чем бинарные.

2.1.2.3. Как и когда выходят изменения


MySQL развивается достаточно быстро в MySQL AB, и мы хотим поделиться новы-
ми разработками с другими пользователями MySQL. Мы стараемся издавать новые вы-
пуски, когда у нас появляются какие-то новые полезные средства, которые могут пона-
добиться многим.
Мы также стремимся помогать пользователям, запрашивающим у нас средства, кото-
рые легко реализовать. Мы отмечаем, что хотят иметь наши зарегистрированные поль-
зователи, и особо отмечаем, чего хотят пользователи, поддерживаемые нами по элек-
тронной почте. Мы стараемся помочь им всем.
Не нужно постоянно загружать новые выпуски. Раздел новостей (News) нашего он-
лайнового руководства предлагает информацию о том, содержит ли новый выпуск то,
что вам нужно. См. http://dev.mysql.com/doc/mysql/en/News.html.
При внесении изменений в MySQL мы придерживаемся следующей политики:
• Выпуски выходят в каждой серии. Номер каждого выпуска - последнее число в
номере версии - на единицу больше, чем у предыдущего выпуска той же серии.
• Производственные (стабильные) выпуски появляются 1-2 раза в год. Однако если
найдены небольшие ошибки, издается выпуск только с исправлениями ошибок.
• Рабочие выпуски и/или исправления к старым выпускам появляются каждые 4-8
недель.
• Бинарные дистрибутивы для различных платформ мы издаем для основных вы-
пусков. Другие люди могут создавать бинарные дистрибутивы для других систем,
но вероятно, не так часто.
• Мы делаем исправления доступными сразу, как только идентифицируем и ис-
правляем маленькие или некритичные, однако ощутимые ошибки. Исправления
доступны немедленно через наши репозитории BitKeeper и включаются в сле-
дующий выпуск.
• В любом случае, если в выпуске обнаружена критическая ошибка, мы издаем но-
вый выпуск сколь возможно скоро. (Как бы хотелось, чтобы и другие компании
поступали так же!)

2.1.2.4. Философия выпусков — ни одной известной ошибки!


Мы тратим значительное время и усилия, чтобы сделать наши выпуски свободными
от ошибок. Мы не выпускаем промежуточных версий MySQL с какими-либо известны-
ми "критическими" повторяющимися ошибками (Под "критической" ошибкой понима-
ется то, что приводит к аварийному завершению MySQL в условиях нормальной экс-
плуатации, либо выдает неверные ответы на нормальные запросы, либо порождает про-
блемы, связанные с безопасностью.)
Мы документируем все обнаруженные проблемы, ошибки и последствия проектных
решений (см. раздел 1.8.7).
Наша цель - исправить все, что можно исправить без риска нарушения стабильности
версии MySQL. В определенных случаях это означает, что мы можем вносить исправле-
84 Глава 2. Установка MySQL

ния в версию, находящуюся в процессе разработки, но не в стабильную (производствен-


ную) версию. Естественно, подобного рода вещи тщательно документируются, дабы
пользователи знали о них.
Ниже представлено описание принятого у нас процесса сборки приложений.
• Мы отслеживаем информацию об ошибках в списках поддержки пользователей,
базе ошибок на http://bugs.mysql.com/ и во внешних списках рассылок, посвя-
щенных MySQL.
• Все отчеты об ошибках текущей версии помещаются в базу данных ошибок.
• Когда мы исправляем ошибку, то всегда стараемся создать для нее тестовый слу-
чай, который затем помещаем в нашу систему тестов, дабы гарантировать, что эта
ошибка никогда не проявится вновь без того, чтобы быть обнаруженной. (Около
90% исправленных ошибок имеют такие тестовые случаи.)
• Мы создаем тестовые случаи для всех новых средств, добавленных в MySQL.
• Прежде чем начать сборку нового выпуска MySQL, мы убеждаемся, что все до-
кументированные повторяемые ошибки в версиях MySQL (3.23.x, 4.0.x и так да-
лее) исправлены. Если что-то исправить невозможно (по причинам каких-то внут-
ренних проектных решений в MySQL), мы соответствующим образом документи-
руем это в руководстве. См. раздел 1.8.7.
• Мы создаем сборку на всех платформах, для которых поддерживаем бинарные
дистрибутивы (свыше 15 платформ) и запускаем на каждой их них существующие
тестовые наборы.
• Мы не издаем бинарных дистрибутивов для тех платформ, для которых тесты не
проходят. Если проблема вызвана ошибкой в исходных текстах, мы исправляем ее
и проводим сборку заново, а также тестируем все системы с нуля.
• Процесс сборки и тестирования занимает 2-3 дня. Если мы получаем сообщение о
критической ошибке в течение этого периода, мы исправляем ее и начинаем про-
цесс сборки заново.
• После публикации бинарных дистрибутивов на http://dev.mysql.com мы рассы-
лаем уведомления об этом через списки рассылки mysql и announce (см. раздел
1.7.1.1). Уведомление включает список всех изменений в выпуске и всех извест-
ных проблем.
• Чтобы предоставить быстрый доступ нашим пользователям к самым последним
средствам MySQL, мы издаем новые выпуски каждые 4-8 недель. Снимки исход-
ных текстов готовятся ежедневно и доступны по адресу:
http://downloads.mysql.com/snapshots.php
• Если, несмотря на все наши усилия, мы получаем сообщение об ошибке после то-
го, как выпуск готов, значит, что-то не так со сборкой для конкретной платформы;
мы сразу исправляем ее и собираем новый выпуск ' а' для этой платформы. Бла-
годаря нашей огромной базе данных, проблемы обнаруживаются достаточно бы-
стро.
• Наша хронология создания качественных выпусков достаточно убедительна. За
последние 150 выпусков нам пришлось делать новые сборки меньше, чем для 10.
В трех случаях ошибка была вызвана библиотекой glibc и в одном - отказом ма-
шины, которая служила нам долгое время верой и правдой.
2.1. Общие вопросы установки 85

2.1.2.5. Бинарные дистрибутивы MySQL, скомпилированные в MySQL АВ


В качестве одной из услуг компания MySQL АВ предоставляет пользователям набор
бинарных дистрибутивов, скомпилированных на собственных системах компании или
на системах, которые принадлежат людям, поддерживающим нас и любезно предостав-
ляющим доступ к своим машинам.
В дополнение к бинарным сборкам, поставляемым в формате пакетов, специфичных
для отдельных платформ, для множества платформ мы предлагаем бинарные дистрибу-
тивы в виде сжатых файлов t a r (файлов . t a r . g z ) . Более подробная информация доступ-
на в разделе 2.2.
Эти дистрибутивы генерируются с помощью сценария Build-tools/Do-compile, ко-
торый компилирует исходный код и затем создает бинарный архив tar.gz, используя
scripts/make_binary_distribution.
Упомянутые дистрибутивы сконфигурированы и собраны с использованием пере-
численных ниже опций и компиляторов. Ту же информацию можно получить, взглянув
на переменные COMP_ENV_INFO и CONFIGURE_LINE внутри сценария bin/mysqlbug, входя-
щего в каждый tar-файл дистрибутива.
Следующие бинарные дистрибутивы собираются на системах для разработки MySQL АВ:
• Linux 2.4.хх х86 с компилятором дсс 2.95.3:
CFLAGS="-O2 -mcpu=pentiumpro" CXX=gcc CXXFLAGS="-O2 -mcpu=pentiumpro
-felideconstructors" ./configure —prefix=/usr/local/mysql
—with-extra-charsets=complex —enable-thread-safe-client
—enable-local-infile —enable-assembler —disable-shared
—with-client-ldflags=-all-static —with-mysqld-ldflags=-allstatic
• Linux 2.4.xx Intel Itanium 2 с компилятором есс (Intel C++ Itanium Compiler 7.0):
CC=ecc CFLAGS="-02 -tpp2 -ip -nolib_inline" CXX=ecc CXXFLAGS=
"-02 -tpp2 -ip -nolib_inline" ./configure —prefix=/usr/local/mysql
—with-extra-charsets=complex —enable-thread-safe-client
—enable-local-infile
• Linux 2.4.xx Intel Itanium с компилятором есс (Intel C++ Itanium Compiler 7.0):
CC=ecc CFLAGS=-tppl CXX=ecc CXXFLAGS=-tppl ./configure —-prefix*
/usr/local/mysql —with-extra-charsets=complex —enable-thread-safeclient
—enable-local-infile
• Linux 2.4.xx alpha с компилятором ссс (Compaq С V6.2-505 / Compaq C + + V6.3-006):
CC=ccc CFLAGS="-fast -arch generic" CXX=cxx CXXFLAGS="-fast -arch
generic -noexceptions -nortti" ./configure —prefix=/usr/local/mysql
—with-extracharsets=complex —enable-thread-safe-client
—enable-local-infile —withmysqld-ldflags=-non_shared
—with-client-ldflags=-non_shared —disable-shared
• Linux 2.x.xx ppc с компилятором дсс 2.95.4:
CC=gcc CFLAGS="-03 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS=
"-03 -fno-omitframe-pointer -felide-constructors -fno-exceptions
-fno-rtti" ./configure —prefix=/usr/local/mysql —localstatedir=
/usr/local/mysql/data —libexecdir=/usr/local/mysql/bin
—with-extra-charsets=complex —enable-threadsafe-client
—enable-local-infile —disable-shared —with-embedded-server
—with-innodb
86 Глава 2. Установка MySQL

• Linux 2.4.хх s390 с компилятором gcc 2.95.3:


CFLAGS=n-O2" CXX=gcc CXXFLAGS="-O2 -felide-constructors" ./configure
—prefix=/usr/local/mysql —with-extra-charsets=complex
—enable-thread-safe-client —enable-local-infile —disable-shared
—with-client-ldflags=-all-static —with-mysqld-ldflags=-all-static
• Linux 2.4.xx x86_64 (AMD64) с компилятором gcc 3.2.1:
CXX=gcc ./configure —prefix=/usr/local/mysql —with-extra-charsets=
complex —enable-thread-safe-client —enable-local-infile —disable-shared
• Sun Solaris 8 x86 с компилятором gcc 3.2.3:
CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3
-fno-oraitframe-pointer -felide-constructors -fno-exceptions -fno-rtti"
./configure —prefix=/usr/local/mysql —localstatedir=
/usr/local/mysql/data —libexecdir=/usr/local/mysql/bin
—with-extra-charsets=complex —enablethread-safe-client
—enable-local-infile —disable-shared —with-innodb
• Sun Solaris 8 SPARC с компилятором gcc 3.2:
COgcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3
-fno-omitframe-pointer -felide-constructors -fno-exceptions - f n o - r t t i "
./configure —prefix=/usr/local/mysql —with-extra-charsets=complex
—enable-thread-safeclient —enable-local-infile —enable-assembler
—with-named-z-libs=no —withnamed-curses-libs=-lcurses —disable-shared
• Sun Solaris 8 SPARC 64-bit с компилятором gcc 3.2:
CC=gcc CFLAGS="-O3 -m64 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3
-m64 -fno-omit-frame-pointer -felide-constructors -fno-exceptions
- f n o - r t t i " ./configure —prefix=/usr/local/mysql —with-extra-charsets=
complex —enable-threadsafe-client —enable-local-infile
—with-named-z-libs=no —with-named-curseslibs=-lcurses —disable-shared
• Sun Solaris 9 SPARC с компилятором gcc 2.95.3:
COgcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3
-fno-omitframe-pointer -felide-constructors -fno-exceptions - f n o - r t t i "
./configure —prefix=/usr/local/mysql —with-extra-charsets=complex
—enable-thread-safeclient —enable-local-infile —enable-assembler
—with-named-curses-libs=-lcurses —disable-shared
• Sun Solaris 9 SPARC с компилятором ее-5.0 (Sun Forte 5.0):
CC=cc-5.0 CXX=CC ASFLAGS="-xarch=v9" CFLAGS="-Xa -xstrconst -mt
-D_FORTEC_ -xarch=v9" CXXFLAGS="-noex -mt -D_FORTEC_ -xarch=v9"
./configure —prefix=/usr/local/mysql —with-extra-charsets=complex
—enable-thread-safeclient —enable-local-infile —enable-assembler
—with-named-z-libs=no—enable-thread-safe-client —disable-shared
• IBM AIX 4.3.2 ppc с компилятором gcc 3.2.3:
CFLAGS="-O2 -mcpu=powerpc -Wa,-many " CXX=gcc CXXFLAGS="-O2 -mcpu=
powerpc -Wa,-many -felide-constructors -fno-exceptions - f n o - r t t i "
./configure —prefix=/usr/local/mysql —with-extra-charsets=complex
—enable-thread-safeclient —enable-local-infile —with-named-z-libs=
no —disable-shared
2.1. Общие вопросы установки 87

• IBM AIX 4.3.3 ррс с компилятором xlC_r (IBM Visual Age C/C++ 6.0):
CC=xlc_r CFLAGS="-ma -02 -qstrict -qoptimize=2 -qmaxmem=8192" CXX=xlC_r
CXXFLAGS ="-ma -02 -qstrict -qoptimize=2 -maxmem=8192" ./configure
—prefix=/usr/local/mysql —localstatedir=/usr/local/mysql/data
—libexecdir=/usr/local/mysql/bin —with-extra-charsets=complex
—enablethread-safe-client —enable-local-infile —with-named-z-libs=
no -disableshared —with-innodb
• I B M A I X 5.1.0 ррс с компилятором gcc 3.3:
CFLAGS="-02 -mcpu=powerpc -Wa,-many" CXX=gcc CXXFLAGS="-02 -mcpu=
powerpc -Wa, -many -felide-constructors -fno-exceptions -fno-rtti"
./configure —prefix=/usr/local/mysql —with-extra-charsets=complex
—enable-thread-safeelient —enable-local-infile —with-named-z-libs=
no —disable-shared
• I B M A I X 5.2.0 ррс с компилятором x l C r (IBM Visual Age C/C++ 6.0):
CC=xlc_r CFLAGS="-ma -02 -qstrict -qoptimize=2 -qmaxmem=8192" CXX=xlC_r
CXXFLAGS="-ma -02 -qstrict -qoptimize=2 -qmaxmem=8192" ./configure
—prefix=/usr/local/mysql —localstatedir=/usr/local/mysql/data
—libexecdir=/usr/local/mysql/bin —with-extra-charsets=complex
—enablethread-safe-client —enable-local-infile —with-named-z-libs=
no -disableshared —with-embedded-server —with-innodb
• H P - U X 10.20 pa-riscl.l с компилятором gcc 3.1:
CFLAGS="-DHPUX -I/opt/dce/include -03 -fPIC" CXX=gcc CXXFLAGS=
"-DHPUX -I/opt/dce /include -felide-constructors -fno-exceptions
-fno-rtti -03 -fPIC" ./configure —prefix=/usr/local/mysql
—with-extra-charsets=complex —enablethread-safe-client
—enable-local-infile —with-pthread —with-named-threadlibs=
-Idee —with-lib-ccflags=-fPIC —disable-shared
• H P - U X 11.00 pa-risc с компилятором aCC (HP ANSI C + + B3910B A.03.50):
CC=cc CXX=aCC CFLAGS=+DAportable CXXFLAGS=+DAportable ./configure
—prefix=/usr/local/mysql —localstatedir=/usr/local/mysql/data
—libexecdir=/usr/local/mysql/bin —with-extra-charsets=complex
—enablethread-safe-client —enable-local-infile —disable-shared
—with-embeddedserver —with-innodb
• H P - U X 11.11 pa-risc2.0 64bit с компилятором aCC (HP A N S I C + + B3910B A.03.33):
CC=cc CXX=aCC CFLAGS=+DD64 CXXFLAGS=+DD64 ./configure
—prefix=/usr/local/mysql —with-extra-charsets=complex
—enable-thread-safe-client —enable-local-infile —disable-shared
• H P - U X 11.11 pa-risc2.0 32bit с компилятором aCC (HP ANSI C + + B3910B A.03.33):
CC=cc CXX=aCC CFLAGS="+DAportable" CXXFLAGS=ll+DAportable" ./configure
—prefix=/usr/local/mysql —localstatedir=/usr/local/mysql/data
—libexecdir=/usr/local/mysql/bin —with-extra-charsets=complex
—enable-threadsafe- client —enable-local-infile —disable-shared
—with-innodb
• H P - U X 11.22 ia64 64bit с компилятором aCC (HP aC++/ANSI С В3910В A.05.50):
88 Глава 2. Установка MySQL

СС=сс СХХ=аСС CFLAGS="+DD64 +DSitanium2" CXXFLAGS="+DD64 +DSitanium2"


./configure —prefix=/usr/local/mysql —localstatedir=/usr/local/mysql/data
—libexecdir=/usr/local/mysql/bin —with-extra-charsets=complex
--enablethread-safe-client —enable-local-infile —disable-shared
—with-embeddedserver —with-innodb
• Apple Mac OS X 10.2 powerpc с компилятором gcc 3.1:
CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3
-fno-omitframe-pointer -felide-constructors -fno-exceptions - f n o - r t t i "
./configure —prefix=/usr/local/mysql —with-extra-charsets=complex
—enable-thread-safeclient —enable-local-infile —disable-shared
• FreeBSD 4.7 i386 с компилятором gcc 2.95.4:
CFLAGS=-DHAVE_BROKEN_REALPATH ./configure —prefix=/usr/local/mysql
—withextra-charsets=complex —enable-thread-safe-client
—enable-local-infile —enable-assembler —with-named-z-libs=not-used
—disable-shared
• FreeBSD 4.7 i386 using LinuxThreads с компилятором gcc 2.95.4:
CFLAGS="-DHAVE_BROKEN_REALPATH -D_USE_UNIX98 -D_REENTRANT -D_THREAD_SAFE
- I / u s r / l o c a l / i n c l u d e / p t h r e a d / l i n u x t h r e a d s " CXXFLAGS=
M
-DHAVE_BROKEN_REALPATH -D USEJJNIX98 -D_REENTRANT -D_THREAD_SAFE
-I/usr/local/include/pthread/linuxthreads" ./configure —prefix=
/usr/local/mysql —localstatedir=/usr/local/mysql/data —libexecdir=
/usr/local/mysql/bin —enablethread-safe-client —enable-local-infile
—enable-assembler —with-namedthread-libs=
M
-DHAVE_GLIBC2_STYLE_GETHOSTBYNAME_R -D_THREAD_SAFE - I
/usr/local/include/pthread/linuxthreads -L/usr/local/lib -11thread
-llgcc_r" —disable-shared —with-embedded-server —with-innodb
• QNX Neutrino 6.2.1 i386 с компилятором gcc 2.95.3qnx-nto 20010315:
CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3
-fno-omitframe-pointer -felide-constructors -fno-exceptions - f n o - r t t i "
./configure —prefix=/usr/local/mysql —with-extra-charsets=complex
—enable-thread-safeclient —enable-local-infile —disable-shared
Следующие бинарные сборки готовятся на системах, любезно предоставляемых на-
шими пользователями. Компания MySQL AB не имеет полного контроля над этими сис-
темами, поэтому мы можем предоставлять только ограниченную поддержку дистрибу-
тивам, собранным на них.
• SCO Unix 3.2v5.0.6 i386 с компилятором gcc 2.95.3:
CFLAGS="-O3 -mpentium" LDFLAGS=-static CXX=gcc CXXFLAGS="-O3 -mpentium
-felideconstructors" ./configure —prefix=/usr/local/mysql
—with-extra-charsets=complex —enable-thread-safe-client
—enable-local-infile —with-named-z-libs=no —enable-thread-safe-client
—disable-shared
• SCO OpenUnix 8.0.0 i386 с компилятором СС 3.2:
CC=cc CFLAGS="-O" CXX=CC ./configure —prefix=/usr/local/mysql
—with-extracharsets=complex —enable-thread-safe-client
—enable-local-infile —withnamed-z-libs=no —enable-thread-safe-client
—disable-shared
2.1. Общие вопросы установки 89

• Compaq Tru64 OSF/1 V5.1 732 alpha с компилятором сс/схх (Compaq С V6.3-029i /
DIGITAL C++V6.1-027):
CC="cc -pthread" CFLAGS="-04 -ansi_alias -ansi_args -fast -inline speed
-speculate a l l " CXX="cxx -pthread" CXXFLAGS="-O4 -ansi_alias -fast
-inline speed -speculate a l l -noexceptions -nortti" ./configure
—prefix=/usr/local/mysql —with-extra-charsets=complex
—enable-thread-safe-client —enable-local-infile —with-prefix=
/usr/local/mysql —with-named-thread-libs="-lpthread -lmach -lexc - l c "
—disable-shared —with-mysqld-ldflags=-all-static
• SGI Irix 6.5 IP32 с компилятором gcc 3.0.1:
CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXXFLAGS="-O3
-fno-omit-framepointer -felide-constructors -fno-exceptions -fno-rtti"
./configure —prefix=/usr/local/mysql —with-extra-charsets=complex
—enable-thread-safeclient —enable-local-infile —disable-shared
• FreeBSD/sparc64 5.0 с компилятором gcc 3.2.1:
CFLAGS=-DHAVEJ3ROKEN_REALPATH ./configure —prefix=/usr/local/mysql
—localstatedir=/usr/local/mysql/data —libexecdir=/usr/local/mysql/bin
—with-extracharsets=complex —enable-thread-safe-client
—enable-local-infile -disableshared —with-innodb
Следующие опции компиляции использовались компанией MySQL AB для сборки
бинарных пакетов в прошлом. Эти бинарные пакеты больше не обновляются, тем не
менее, мы приводим опции компиляторов в справочных целях.
• Linux 2.2.хх SPARC с компилятором egcs 1.1.2:
CC=gcc CFLAGS="-03 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3
-fno-omitframe-pointer -felide-constructors -fno-exceptions -fno-rtti"
./configure —prefix=/usr/local/mysql —with-extra-charsets=complex
—enable-thread-safeclient —enable-local-infile —enable-assembler
—disable-shared
• Linux 2.2.x with x686 с компилятором gcc 2.95.2:
CFLAGS="-03 -mpentiumpro" CXX=gcc CXXFLAGS="-03 -mpentiumpro
-felideconstructors -fno-exceptions -fno-rtti" ./configure
—prefix=/usr/local/mysql —enable-assembler —with-mysqld-ldflags=
- a l l - s t a t i c —disable-shared —withextra-charsets=complex
• SunOS 4.1.4 2 sun4c с компилятором gcc 2.7.2.1 :
CC=gcc CXX=gcc CXXFLAGS="-03 -felide-constructors" ./configure —prefix=
/usr/local/mysql —disable-shared —with-extra-charsets=complex
—enable-assembler
• SunOS 5.5.1 (и предшествующие версии) sun4u с компилятором egcs 1.0.3а или
2.90.27, либо gcc 2.95.2 и более новой версии:
CC=gcc CFLAGS="-03" CXX=gcc CXXFLAGS="-O3 -felide-constructors
-fno-exceptions -fno-rtti" ./configure —prefix=/usr/local/mysql
—with-low-memory —withextra-charsets=complex —enable-assembler
• SunOS 5.6 i86pc с компилятором gcc 2.8.1:
90 Глава 2. Установка MySQL

CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure —prefix=/usr/local/mysql


—with-lowmemory —with-extra-charsets=complex
• BSDI BSD/OS 3.1 i386 с компилятором gcc 2.7.2.1:
CC=gcc CXX=gcc CXXFLAGS=-0 ./configure ~prefix=/usr/local/mysql
—with-extracharsets=complex
• BSDI BSD/OS 2.1 i386 с компилятором gcc 2.7.2:
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure —prefix=/usr/local/mysql
—with-extracharsets=complex
• AIX 2 4 c компилятором gcc 2.7.2.2:
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure —prefix=/usr/local/mysql
—with-extracharsets=complex
Любой, кому известны более оптимальные наборы опций для конфигурации компи-
ляторов из приведенных выше перечней, может прислать их в список рассылки MySQL
internals (см. раздел 1.7.1.1).
Дистрибутивы в формате RPM до версии MySQL 3.22 предоставлены пользователя-
ми. Начиная с MySQL 3.22, дистрибутивы RPM генерируются специалистами компании
MySQL AB.
Если нужно собрать отладочную версию MySQL, добавьте опцию --with-debug или
—with-debug=full к приведенным выше строкам конфигурации и удалите опции
-fomit-frame-pointer.

2.1.3. Как получить MySQL


Получить информацию о текущей версии, а также инструкции по загрузке можно на
домашней странице MySQL по адресу http://www.mysql.com/.
Главный зеркальный сайт доступен по адресу h t t p : //mirrors. sunsite.dk/mysql/.
Полный список зеркальных сайтов, на которых можно получить MySQL, находится
по адресу http://dev.mysql.com/downloads/mirrors.html. Там же приводится инфор-
мация о том, как добавить собственный зеркальный сайт MySQL и куда сообщать о не-
действительных зеркальных сайтах.

2.1.4. Проверка целостности пакета с помощью


контрольных сумм MD5 или GnuPG
После загрузки подходящего пакета MySQL и до его установки потребуется убедить-
ся в его целостности, аутентичности и действительности.
Компания MySQL AB предлагает три способа проверки целостности:
• Контрольные суммы MD5.
• Криптографические подписи с использованием системы защиты конфиденциаль-
ности GnuPG (GNU Privacy Guard).
• Встроенный механизм верификации для RPM-пакетов.
В приведенных ниже разделах эти методы описываются более подробно.
Если обнаруживается, что контрольная сумма MD5 или GPG-подписи не совпада-
ют, первым делом нужно попытаться загрузить соответствующий пакет еще раз, воз-
можно, с другого зеркального сайта. Если повторная проверка целостности пакета ока-
2.1. Общие вопросы установки 91

зывается снова неудачной, известите нас об этом инциденте по электронной почте


[email protected] или [email protected], включив в сообщение полное наименование
пакета и адрес сайта, откуда он был загружен. Не используйте для этого систему уве-
домления об ошибках.

2.1.4.1. Проверка контрольной суммы MD5


После того, как пакет MySQL загружен, следует убедиться, что его контрольная сум-
ма MD5 совпадает с той, которая указана на странице загрузки. Каждый пакет имеет
индивидуальную контрольную сумму, которую можно проверить с помощью следую-
щей команды (здесь имя_пакета - наименование выгруженного пакета):
shell> md5sum имя_пакета
Пример:
shell> md5sum mysql-standard-4.0.17-pc-linux-i686.tar.gz
60f5fe969d61c8f82e4f7f62657elf06 mysql-standard-4.0.17-pc-linux-i686.tar.gz
Вы должны убедиться, что результирующая контрольная сумма (строка шестнадца-
теричных цифр) совпадает с указанной на странице загрузки непосредственно под име-
нем соответствующего пакета.
Помните, что не все операционные системы поддерживают команду md5sum. В некото-
рых из них она называется md5, а другие вовсе ее не имеют. В ОС Linux эта команда явля-
ется частью пакета GNU Text Utilities, который доступен для широкого спектра плат-
форм. Исходные тексты можно загрузить с http://www.gnu.org/software/textutils. Ес-
ли в системе установлен пакет OpenSSL, можно воспользоваться командой openssl md5
имя_пакета. Реализации команды md5 для DOS/Windows доступны по адресу
http://www.fourmilab.ch/md5.

2.1.4.2. Проверка подписи с использованием GnuPG


Другой способ проверки целостности и подлинности пакета предполагает использо-
вание криптографических подписей. Это более надежный метод, чем контрольные сум-
мы MD5, требующий, однако, больших усилий.
Начиная с MySQL 4.0.10 (февраль 2003 года) MySQL AB стала подписывать загру-
жаемые пакеты с помощью GnuPG (GNU Privacy Guard). GnuPG - это программа с откры-
тым исходным кодом, представляющая собой альтернативу хорошо известной Pretty
Good Privacy (PGP) от Фила Циммермана (Phil Zimmermann). Более подробную инфор-
мацию о GnuPG, а также о том, как ее получить и установить, ищите на сайте
http://www.gnupg.org. Большинство дистрибутивов Linux поставляются вместе с GnuPG,
устанавливаемой по умолчанию. Дополнительная информация об OpenPGP доступна на
сайте http://www.openpgp.org.
Для проверки подписи конкретного пакета сначала нужно получить копию открыто-
го ключа GPG от MySQL AB. Его можно загрузить с http: //www. keyserver.net.
Ключ, который вам необходим, называется [email protected]. В качестве альтернати-
вы можете воспользоваться приведенным ниже текстом:
Key ID:
pub 1024D/5072E1F5 2003-02-03
MySQL Package signing key (www.mysql.com) <[email protected]>
Fingerprint: A4A9 4068 76FC BD3C 4567 70C8 8C71 8D3B 5072 E1F5
Public Key (ASCII-armored):
92 Глава 2. Установка MySQL

BEGIN PGP PUBLIC KEY BLOCK


Version: GnuPG vl.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org
mQGiBD4+owwRBAC14GIfUfCyEDSIePvEW3SAFUdJBtoQHH/nJKZyQT7h9bPlUWC3RODjQReyCITR
rdwyrKUGku2FmeVGwn2u2WmDMNABLnpprWPkBdCk96+OmSLN9brZfw2vOUgCmYv2hW0hyDHuvYlQ
A/BThQoADgj8AW6/0Lo7VlW9/8VuHP0gQwCgvzV3BqOxRznNCRCRxAuAuVztHRcEAJooQKl+iSiu
nZMYDlWufeXfshc57S/+yeJkegNWhxwR9pRWVArNYJdDRT+rf2RUe3vpquKNQU/hnEIUHJRQqYHo
8gTxvxXNQc7fJYLVK2HtkrPbP72vwsEKMYhhr0eKCbtLGfls9krjJ6sBgACyP/Vb7hiPwxh6rDZ7
ITnEkYpXBACmWpP8NJTkamEnPCia2ZoOHODANwpUkP43I7jsDmgtobZX9qnrAXw+uNDIQJEXM6FS
bi0LLtZciNlYsafwAPEOMDKpMqAK6lyisNtPvaLd81H0bPAnWqcyefeprv0sxxqUEMcM3o7wwgfN
83POkDasDbs3pjwPhxvhz6//62zQJ7Q7TXlTUUwgUGFja2FnZSBzaWduaW5nIGtleSAod3d3Lml5
c3FsLmNvbSkgPGJlaWxkQG15c3FsLmNvbT6lXQQTEQIAHQUCPj6jDAUJCWYBgAULBwoDBAMVAwID
FgIBAheAAAoJEIxxjTtQcuHlcY4AnilUwTXn8MatQOiG0a/bPxrvK/gCAJ4oinSNZRYTnblChwFa
azt7PF3qzIhMBBMRAgAMBQI+PqPRBYMJZgC7AAoJEElQ4SqycpHyJOEAnlmxHijft00bKXvucSo/
pECUmppiAJ41M9MRVj5VcdH/KN/KjRtW6tHFPYhMBBMRAgAMBQI+QoIDBYMJYiKJAAoJELblzU3G
uiQ/lpEAoIhpp6BozKI8p6eaabzF5MUH58pAKCu/ROofK8JEg2aLos+5zEYrB/LsrkCDQQ+PqMd
EAgA7+GJfxbMdY4wslPnjH9rF4N2qfWsEN/lxaZoJYc3a6M02WCnH16ahT2/tBK2wlQI4YFteR47
gCvtgb6OUHffOo2HfLmRDRiRjdlDTCHqeyX7CHhcghj/dNRlW2Z015QFEcmV9U0Vhp3aFfWC4Uj
fs3LU+hkAWzE7zaD5cH9J7yv/6xuZVw411x0h4UqsTcWMu0iMlBzELqXlDY7LwoPEb/O9Rkbf4fm
LellEzIaCa4PqARXQZc4dhSinMt6K3X4BrRsKTfozBu74F47D8Ilbf5vSYHbuE5p/loIDznkg/p8
kW+3FxuWrycciqFTcNz215yyX39LXFnlLzKUb/F5GwADBQf+Lwqqa8CGrRfsOAJxim63CHfty5mU
c5rUSnTslGYEIOCRlBeQauyPZbPDsDD9MZlZaSafanFvwFG6Llx9xkU7tzq+VKLoWkm4u5xf3vn5
5VjnSdlaQ9eQnUcXiL4cnBGoTbOWI39EcyzgslzBdC++MPjcQTcA7p6JUVsP6oAB3FQWg54tuUo0
Ec8bsM8b3Ev42LmuQT5NdKHGwHsXTPtl0klk4bQk4OajHsiylBMahpT27jWjJlMiJc+IWJ0mghkK
Ht926s/ymfdf5HkdQlcyvsz5tryVI3Fx78XeSYfQvuuwqp2H139pXGEkg0n6KdUOetdZWhe70YGN
PwlyjWJTlIhMBBgRAgAMBQI+PqMdBQkJZgGAAAoJEIxxjTtQcuH17p4An3rlQpVC9yhnW2cSAjq+
kr72GX0eAJ4295kl6NxYEuFApmrl+0uUq/SlsQ===YJkx
END PGP PUBLIC KEY BLOCK
Выполните импорт этого ключа в персональное хранилище открытых ключей GPG с
использованием команды gpg --import.
Например, если ключ был сохранен в файле mysqljpubkey.asc, команда импорта бу-
дет выглядеть следующим образом:
shell> gpg —import mysqljpubkey.asc
В документации по GPG имеется информация о том, как работать с открытыми клю-
чами.
После загрузки открытого ключа приступайте к загрузке необходимого пакета
MySQL и соответствующей подписи, которая находится на той же странице выгрузки.
Файл подписи имеет то же имя, что и файл дистрибутива, и расширение .asc.
Например:
Distribution file mysql-standard-4.0.17-pc-linux-i686. t a r . gz
Signature file mysql-standard-4.0.17-pc-linux-i686.tar.gz.asc
Убедитесь, что оба файла расположены в одном и том же каталоге, после чего запус-
тите следующую команду для проверки подписи файла дистрибутива:
shell> gpg —verify имя_пакета.asс
Пример:
shell> gpg —verify mysql-standard-4.0.17-pc-linux-i686.tar.gz.asc
gpg: Warning: using insecure memory!
2.1. Общие вопросы установки 93

gpg: S i g n a t u r e made Mon 03 Feb 2003 08:50:39 PM MET


u s i n g DSA key ID 5072E1F5
gpg: Good s i g n a t u r e from
"MySQL Package s i g n i n g key (www.mysql.com) <[email protected]>"
Сообщение "Good signature..." говорит о том, что все в порядке. Предупреждение
" u s i n g i n s e c u r e memory" ("использование незащищенной памяти") можно проигнори-
ровать.

2.1.4.3. Проверка подписи с использованием RPM


Для пакетов в формате RPM не существует отдельных файлов подписей. Они имеют
встроенные подписи GPG и контрольные суммы MD5. Проверить пакет можно с помо-
щью следующей команды:
s h e l l > rpm —checksig имя^пакета.rpm
Пример:
s h e l l > rpm —checksig MySQL-server-4.0.10-0.i386.rpm
MySQL-server-4.0.10-0.i386.rpm: md5 gpg OK

На заметку!
Если вы используете RPM 4.1, и он выдает сообщение вида: "(GPG) NOT OK (MISSING KEYS:
GPG#5072e1f5)"f даже если открытый ключ MySQL уже импортирован в ваше собственное хра-
нилище ключей GPG, вначале потребуется выполнить импорт его в хранилище ключей RPM. Де-
ло в том, что RPM 4.1 больше не использует хранилище ключей GPG (как и самого GPG). Вместо
этого он поддерживает свое собственное хранилище, поскольку это приложение уровня системы,
а хранилище ключей GPG - файл, специфичный для каждого пользователя. Чтобы импортировать
открытый ключ MySQL в хранилище ключей RPM, вначале получите его, как описано в предыдущем
разделе. Затем воспользуйтесь командой rpm —import для импорта ключа. Например, если от-
крытый ключ хранится в файле mysql_pubkey. as с, команда импорта будет выглядеть так:
s h e l l > rpm —import mysql_pubkey.asc

2.1.5. Расположение каталогов установки


Этот раздел описывает расположение каталогов по умолчанию, которое получается
при установке бинарного или исходного дистрибутивов, предоставляемых компанией
MySQL AB. Если вы устанавливаете дистрибутив, полученный от другого поставщика,
расположение каталогов может оказаться другим.
В среде Windows каталогом установки по умолчанию является C:\raysql, при этом в
нем содержатся следующие подкаталоги:

Подкаталог Содержит
bin Клиентские программы и сервер mysqld.
data Файлы журналов и баз данных.
Docs Документация.
examples Примеры программ и сценариев.
include Включаемые файлы заголовков.
lib Библиотеки.
scripts Сценарии утилит.
share Файлы сообщений об ошибках.
94 Глава 2. Установка MySQL

После установки, выполненной из RPM-дистрибутивов Linux, файлы располагаются


в следующих каталогах:
Каталог Содержит
/usr/bin Клиентские программы и сценарии.
/usr/sbin Сервер mysqld.
/var/lib/mysql Файлы журналов и баз данных.
/usr/ share/doc/packages Документация.
include/usr/include/mysql Включаемые файлы заголовков.
lib/usr/lib/mysql Библиотеки.
/usr/share/mysql Сообщения об ошибках и файлы символьных наборов.
sql-bench/usr/share/sql-bench Тесты производительности.
В среде Unix бинарный дистрибутив из файла t a r устанавливается простой распа-
ковкой его в каталог по вашему выбору (обычно /usr/ l o c a l /mysql). При этом создаются
следующие подкаталоги:
Подкаталог Содержит
bin Клиентские программы и сервер mysqld.
data Файлы журналов и баз данных.
docs Документация.
include Включаемые файлы заголовков.
lib Библиотеки.
scripts mysql_install_db.
share/mysql Файлы сообщений об ошибках.
sql-bench Тесты производительности.
Исходный дистрибутив устанавливается после соответствующего конфигурирования
и компиляции. По умолчанию на шаге установки файлы размещаются в следующих
подкаталогах каталога /usr/local:
Подкаталог Содержит
bin Клиентские программы и сценарии.
include /mysql Включаемые файлы заголовков.
info Документация в Info-формате.
lib/mysql Библиотеки.
libexec Сервер mysqld.
share /mysql Файлы сообщений об ошибках.
sql-bench Тесты производительности.
var Файлы журналов и баз данных.
Внутри каталога установки расположение каталогов и файлов для исходного дистри-
бутива отличается от бинарного в следующих моментах:
• Сервер mysqld устанавливается в подкаталог l i b e x e c вместо подкаталога bin.
• Подкаталог данных - v a r вместо data.
• m y s q l _ i n s t a l l _ d b устанавливается в подкаталог b i n вместо s c r i p t s .
• Подкаталоги библиотеки и файлов заголовков - соответственно, i n c l u d e /mysql и
lib/mysql вместо include и lib.
2.2. Стандартная установка MySQL из бинарного дистрибутива 95

Вы можете создать собственную бинарную установку из скомпилированного исход-


ного дистрибутива с помощью сценария scripts/make_binary_distribution, который
находится в каталоге верхнего уровня исходного дистрибутива.

2.2. Стандартная установка MySQL


из бинарного дистрибутива
В настоящем разделе раскрываются особенности установки MySQL на платформах,
для которых мы предлагаем дистрибутивы в родном формате пакетов этих платформ (то,
на что часто ссылаются как на "бинарную установку"). Бинарные дистрибутивы доступ-
ны также и для множества других платформ. В разделе 2.2.5 представлены общие инст-
рукции по установке этих пакетов, которые применимы для всех платформ.
В разделе 2.1 можно найти информацию о том, какие другие бинарные дистрибутивы
существуют и как их получить.

2.2.1. Установка MySQL под Windows


Процесс установки MySQL под Windows включает следующие шаги:
1. Получение и установка дистрибутива.
2. Настройка файла опций, если необходимо.
3. Выбор сервера, который должен использоваться.
4. Запуск сервера.
5. Установка паролей для начальных пользовательских учетных записей MySQL.
Дистрибутив MySQL дня платформы Windows доступен в следующих двух форматах:
• Бинарный дистрибутив, содержащий программу установки, которая инсталлирует
все необходимое таким образом, что можно будет запустить сервер немедленно.
• Исходный дистрибутив, содержащий весь исходный код и файлы поддержки, не-
обходимые для сборки исполняемых файлов с помощью компилятора VC++ 6.0.
Вообще говоря, вы должны использовать бинарный дистрибутив. Это проще, и вам
не понадобятся никакие дополнительные инструменты, чтобы поднять и запустить
MySQL.
В этом разделе объясняется, как устанавливать MySQL в среде Windows из бинарно-
го дистрибутива. Вопросам установки из исходного дистрибутива посвящен раздел 2.3.6.

2.2.1.1. Требования к системе на базе Windows


Для запуска MySQL под управлением Windows необходимы следующие компоненты:
• 32-разрядная операционная система Windows, такая как 9х, Me, NT, 2000 или ХР.
Семейство NT (Windows NT, 2000 и ХР) позволяет запускать сервер MySQL как
системную службу (см. раздел 2.2.1.7).
• Поддержка протокола TCP/IP.
• Копия бинарного дистрибутива для Windows, которую можно загрузить с
http://dev.mysql.com/downloads (см. раздел 2.1.3).
1 На заметку!
Jf В случае загрузки дистрибутива через FTP рекомендуем использовать адекватный FTP-клиент, с
'v. поддержкой догрузки, дабы избежать повреждения файлов в процессе загрузки.
96 Глава 2. Установка MySQL

• WinZip или другой Windows-инструмент, способный читать файлы .zip, для рас-
паковки файла дистрибутива.
• Достаточный объем свободного пространства на жестком диске, чтобы распако-
вать, установить и создать базы данных в соответствии с существующими по-
требностями.
• Если планируется подключение к серверу MySQL через интерфейс ODBC, пона-
добится также драйвер MyODBC.
• Если понадобится оперировать с таблицами размером более 4 Гбайт, устанавли-
вайте MySQL в раздел NTFS или более новой файловой системы. Не забывайте
при создании таблиц использовать MAXROWS и AVGROWLENGTH.

2.2.1.2. Установка бинарного дистрибутива под Windows


Для установки MySQL под управлением Windows с использованием бинарного дист-
рибутива выполните следующую процедуру:
1. Если вы работаете на компьютере под управлением Windows NT, 2000 или ХР,
убедитесь, что вы вошли в систему от имени пользователя с привилегиями адми-
нистратора.
2. Если осуществляется модернизация более ранней установки MySQL, необходимо
остановить существующий сервер MySQL. На машинах с Windows NT, 2000 или
ХР, если сервер запущен как системная служба Windows, остановите его командой:
С:\> NET STOP MySQL
Если вы планируете использовать другой сервер (например, mysqld-max вместо
mysqld), удалите существующую службу:
С:\> C:\mysql\bin\mysqld —remove
Службу можно переустановить, чтобы после модернизации пользоваться пра-
вильным сервером. Если сервер MySQL выполняется не как системная служба,
остановите его так:
С:\> C:\raysql\bin\mysqladmin -u root shutdown
3. Завершите программу WinMySQLAdmin, если она выполняется.
4. Распакуйте файл дистрибутива во временный каталог.
5. Запустите программу setup.exe, чтобы начать процесс установки. Если вы хотите
установить MySQL в каталог, отличный от каталога по умолчанию (C:\mysql), с
помощью кнопки Browse (Обзор) укажите требуемый каталог. Если для установ-
ки MySQL выбран не каталог по умолчанию, то при каждом запуске сервера при-
дется указывать его местоположение. Самый простой способ сделать это - вос-
пользоваться файлом опций, как описано в разделе 2.2.1.3.
6. Завершите процесс установки.
На заметку!
Ранние дистрибутивы альфа-версий MySQL 4.1 для Windows не содержали программы установ-
ки. Дистрибутив версии 4.1 - это просто Zip-файл, который нужно просто распаковать в каталог, в
котором будет выполняться установка MySQL. Например, чтобы установить m y s q l - 4 . 1 . 1 -
alpha-win.zip в каталог C:\mysql, распакуйте файл дистрибутива на диск С:, затем пере-
именуйте полученный в результате каталог из mysql-4.1.1-alpha в mysql.
2.2. Стандартная установка MySQL из бинарного дистрибутива 97

Если выполняется модернизация ранней версии до MySQL 4.1, вам понадобится


предварительно сохранить существующий каталог data, который содержит таблицы
привилегий и ваши собственные базы данных. Перед установкой версии 4.1 остановите
сервер, если он запущен, и сохраните каталог data где-то в другом месте. После этого
переименуйте существующий каталог С: \raysql или просто удалите его. Затем установи-
те MySQL 4.1, как описано выше, и замените содержимое каталога data содержимым
старого каталога data. Это позволит избежать потери ваших баз данных. Запустите но-
вый сервер и обновите таблицы привилегий (см. раздел 2.5.8).

2.2.1.3. Подготовка MySQL-окружения для Windows


Если при запуске сервера нужно использовать какие-то начальные опции, их можно
указать в командной строке либо поместить в файл опций. Те из них, которые будут ис-
пользоваться при каждом запуске сервера, удобнее поместить в файл, описывающий
вашу конфигурацию MySQL. В частности, это справедливо при следующих обстоятель-
ствах:
• Размещение каталога установки или каталога данных отличается от принятого по
умолчанию (С: \mysql и С: \mysql\data).
• Требуется настроить установки сервера. Например, чтобы использовать транзак-
ционные таблицы innoDB в MySQL 3.23, нужно вручную добавить несколько до-
полнительных строк в файл опций, как описано в разделе 9.4. (Как и в MySQL 4.0,
InnoDB создает файлы данных и файлы журналов по умолчанию в каталоге data.
Это означает, что необходимость в явном конфигурировании InnoDB отсутствует.
Если хотите, можете по-прежнему это делать, и в этом случае вам поможет файл
опций.)
В среде Windows программа установки MySQL размещает каталог данных непосред-
ственно внутри каталога, куда устанавливается MySQL. Если вы хотите разместить ка-
талог данных в другом месте, туда нужно будет скопировать все его содержимое. На-
пример, по умолчанию программа установки помещает MySQL в каталог C:\mysql, а
данные - в С: \mysql\data. Если вы хотите выбрать в качестве каталога данных, скажем,
Е: \raydata, потребуется выполнить следующие действия:
• Перенести каталог данных из С: \mysql\data в Е: \mydata.
• С помощью опции —datadir указать новое местоположение каталога данных при
каждом запуске сервера.
Сразу после запуска в среде Windows сервера MySQL ищет опции в двух файлах:
my. ini в каталоге Windows и С: \my. cnf. Каталог Windows обычно имеет имя С: \WINDOWS
или С: \WinNT. Точное его расположение хранится в переменной окружения WINDIR; ото-
бразить содержимое этой переменной можно помощью следующей команды:
С:\> echo %WINDIR%
MySQL ищет опции сначала в файле my.ini, затем в my.cnf. Однако во избежание
конфликтов лучше использовать только один их упомянутых файлов. Если ваш компью-
тер использует начальный загрузчик (boot loader), в котором диск С: не является загру-
зочным, то у вас только один выбор - использовать my. ini. Какой бы файл опций вы ни
использовали, это должен быть простой двумерный текстовый файл.
Файл опций можно создать и модифицировать с помощью любого текстового редак-
тора наподобие Notepad (Блокнот). Например, если MySQL установлен в каталоге
98 Глава 2. Установка MySQL

E:\mysql, а каталогом данных является E:\mydata\data, можно создать файл опций и


установить в его разделе [mysqld] следующие значения параметров basedir и datadir:
[mysqld]
# set basedir to your i n s t a l l a t i o n path
# задайте для basedir каталог установки
basedir=E:/mysql
# set datadir to the location of your data directory
# задайте для datadir каталог данных
datadir=E:/raydata/data
Обратите внимание, что пути каталогов Windows задаются в файле опций с обычны-
ми косыми чертами (с правым уклоном) вместо обратных (с левым уклоном). Если вы
используете обратные косые черты, они должны дублироваться.
Другой способ управления файлом опций предполагает работу с инструментом
WinMySQLAdmin. Эта программа находится в каталоге bin вашей установки MySQL, там
же хранится и справочный файл с инструкциями по ее применению. С помощью
WinMySQLAdmin можно редактировать файл опций, однако следует помнить о следующих
моментах:
• WinMySQLAdmin работает только с файлом my. ini.
• Если WinMySQLAdmin находит файл C:\my.cnf, то переименовывает его в
С:\my_cnf .bak, чтобы таким образом его отключить.
Теперь все готово к запуску сервера.

2.2.1.4. Выбор сервера для Windows


Начиная с версии MySQL 3.23.38, дистрибутив для Windows включает бинарные
файлы и нормального сервера, и сервера MySQL-Max. Ниже приведен список различных
серверов MySQL, из которых можно выбрать тот, который наиболее точно соответству-
ет существующим потребностям.
Бинарный файл Описание
mysqld Скомпилирован с полной отладочной информацией, автоматической
проверкой распределения памяти, символическими связями и поддерж-
кой таблиц InnoDB и BDB.
mysqld-opt Оптимизированный вариант. Начиная с версии 4.0, включает поддержку
InnoDB. До версии 4.0 этот вариант не поддерживал транзакционные
таблицы.
mysqld-nt Оптимизированный вариант сервера для Windows NT, 2000 и ХР с под-
держкой именованных каналов.
mysqld-max Оптимизированный вариант с поддержкой символических связей и таб-
лиц InnoDB и BDB.
mysqld-max-nt To же самое, что и mysqld-max, но с поддержкой именованных каналов.

Все перечисленные программы оптимизированы для современных процессоров Intel,


и должны работать на любом процессоре семейства Intel i386 или более новых.
MySQL поддерживает протокол TCP/IP на всех Windows-платформах, mysqld-nt и
mysqld-max-nt кроме того поддерживают именованные каналы в средах Windows NT,
Windows 2000 и Windows ХР. Однако, независимо от платформы, протоколом по умол-
2.2. Стандартная установка MySQL из бинарного дистрибутива 99

чанию является TCP/IP. (Именованные каналы во многих конфигурациях Windows мед-


леннее, чем TCP/IP.) Применение именованных каналов обусловлено следующими фак-
торами:
• Начиная с MySQL 3.23.50, именованные каналы включаются, только если сервер
запущен с опцией —enabled-named-pipe. Эту опцию нужно указывать явно, по-
тому что некоторые пользователи сталкивались с проблемами при остановке сер-
вера, когда применялись именованные каналы.
• Подключения по именованным каналам возможны только с серверами mysqld-nt
и mysqld-max-nt, и только при запуске их под управлением версий Windows, под-
держивающих этот протокол (NT, 2000, ХР).
• Эти серверы могут работать в Windows 98 или Windows Me, но только если уста-
новлен протокол TCP/IP. Именованные каналы в этих случаях не могут быть ис-
пользованы.
• Под управлением Windows 95 эти серверы не работают.
% На заметку!
?Л В большинстве примеров в последующих разделах в качестве имени сервера используется
|? mysqld. Если для запуска выбран другой сервер, такой как mysqld-opt, соответствующим об-
& разом измените команды, приведенные в примерах. Существует одна важная причина для выбо-
il pa другого сервера, а именно то обстоятельство, что в mysqld реализована полная поддержка
t; отладки, и, следовательно, этот сервер использует больший объем памяти и функционирует
1\ медленнее, нежели другие серверы для Windows.

2.2.1.5. Запуск сервера в первый раз


В средах Windows 95, 98 или Me клиенты MySQL всегда подключаются к серверу
черех TCP/IP. (В результате к вашему серверу MySQL может подключиться любая ма-
шина в сети.) По этой причине перед запуском MySQL следует убедиться, что на маши-
не корректно установлена поддержка TCP/IP. Файлы поддержки TCP/IP находятся на
компакт-диске дистрибутива Windows.
Необходимо отметить, что если используется старый выпуск Windows 95 (например,
OSR2), весьма вероятно, что в нем установлен старый пакет Winsock. MySQL же требует
применения Winsock 2. Новейший пакет Winsock можно получить на сайте
http://www.microsoft.com. Windows 98 включает новую библиотеку Winsock 2, поэто-
му в этой системе ее обновлять не нужно.
На NT-подобных системах, таких как Windows NT, 2000 или ХР, клиент может вы-
бирать между TCP/IP и именованными каналами (разумеется, если сервер поддерживает
подключения по именованным каналам).
Информация о выборе программы сервера для запуска представлена в разделе 2.2.1.4.
Настоящий раздел дает общее представление о запуске сервера MySQL. Последую-
щие разделы предоставляют более подробную информацию для отдельных версий
Windows.
В приведенных здесь примерах предполагается, что MySQL установлен в каталог по
умолчанию, C:\mysql. Если у вас MySQL установлен в другой каталог, должным обра-
зом исправьте имена каталогов, упомянутые в примерах.
Тестирование лучше всего выполнять из командной строки в консольном окне (назы-
ваемом еще "окном DOS"). В этом случае сообщения о состоянии сервера выдаются в то
же окно. Если что-то не так с конфигурацией, эти сообщения помогут идентифициро-
вать и решить любые проблемы.
102 Глава 2. Установка MySQL

Чтобы заставить MySQL работать с протоколом TCP/IP в Windows NT, потребуется


установить пакет обновлений Service Pack 3 (или более новый).
Перед установкой MySQL как службы Windows необходимо вначале остановить те-
кущий сервер, если он запущен. Это делается с помощью следующей команды:
С:\> C:\mysql\bin\mysqladmin -u root shutdown
Эта команда запускает утилиту администрирования mysqladmin, которая подключа-
ется к серверу и посылает ему команду останова. Утилита подключается к серверу с ис-
пользованием root - стандартной учетной записи администратора в системе привилегий
MySQL. Следует отметить, что система привилегий MySQL совершенно не зависит от
имен пользователей, которые применялись для входа в Windows.
Теперь установите сервер как службу:
С:\> mysqld --install
Если при указании только имени сервера возникают проблемы с установкой mysqld
как службы, попробуйте задать полный путь:
С:\> C:\mysq\bin\mysqld —install
Для версии MySQL 4.0.2 после опции — i n s t a l l можно указать также и имя службы. В
MySQL 4.0.3 после имени службы можно дополнительно задать опцию —defaults-file,
чтобы указать, откуда сервер должен получить настройки при запуске. Ниже представле-
ны правила, определяющие имя службы и файлов опций, которые использует сервер.
• Если вы не указываете имя службы, сервер использует имя по умолчанию, MySQL,
и читает опции из раздела [mysqld] стандартного файла опций.
• Если вы указываете имя службы после опции — i n s t a l l , сервер игнорирует раз-
дел [mysqld] и вместо него читает опции из раздела, имя которого совпадает с
именем службы в стандартном файле опций.
• Если вы указываете опцию —defaults-file после имени службы, сервер игнори-
рует стандартный файл опций и читает их только из раздела [mysqld] названного
файла.
? На заметку!
% До версии MySQL 4.0.17 сервер, установленный как служба Windows, порождал проблемы при
'^ запуске, если его полный путь или имя службы содержали пробелы. По этой причине следует из-
|| бегать установки MySQL в каталог вроде С: \Program F i l e s , а также использовать пробелы в
& имени службы.

В редком случае, когда вы устанавливаете сервер с опцией — i n s t a l l , но без имени


службы, сервер устанавливается в виде службы с именем MySQL.
В качестве более сложного примера рассмотрим приведенную ниже команду:
С:\> С:\mysql\bin\mysqld —install mysql—defaults-file=C:\my-opts.cnf
Здесь после опции - - i n s t a l l указывается имя службы. Если не задать опцию
—defaults-file, эта команда заставит сервер читать раздел [mysql] стандартного фай-
ла опций (что не очень хорошо, поскольку этот раздел предназначен для клиентских
программ). Однако, поскольку опция —defaults-file присутствует, сервер прочтет
свои настройки из указанного файла, и только из его раздела [mysqld].
Опции можно также задать как Start parameters (Параметры запуска) в Windows-
утилите Services.
2.2. Стандартная установка MySQL из бинарного дистрибутива 103

После того, как сервер MySQL установлен и сконфигурирован как служба, он будет
автоматически стартовать при запуске Windows. Его также можно запустить немедленно
с помощью утилиты Services либо по команде NET START MySQL. Команда NET не чувст-
вительна к регистру символов.
Когда сервер MySQL выполняется как служба, он не имеет доступа к консольному
окну, поэтому нельзя увидеть никаких сообщений от него. Если mysqld не запустился,
просмотрите журнал ошибок на предмет поиска причин проблемы. Журнал ошибок хра-
нится в каталоге С: \mysql\data и представляет собой файл с расширением .err.
Если mysqld выполняется как служба, его можно остановить той же утилитой
Services, командой NET STOP MySQL или командой mysqladmin shutdown. Если на мо-
мент завершения работы Windows служба функционирует, она будет остановлена авто-
матически.
Начиная с MySQL 3.23.44, имеется выбор устанавливать сервер как службу Manual,
если вы не хотите, чтобы сервер MySQL запускался автоматически при загрузке систе-
мы. Для этого вместо опции - - i n s t a l l укажите опцию —install-manual:
С:\> С:\mysql\bin\mysqld —install-manual
Чтобы удалить сервер, установленный как служба, сначала остановите его. Затем
воспользуйтесь опцией --remove для его удаления:
С:\> С:\mysql\bin\mysqld —remove
С версиями MySQL до 3.23.49 была связана одна проблема с автоматической оста-
новкой службы, а именно: ОС Windows ожидала всего несколько секунд ее завершения,
затем, по истечении некоторого лимита времени, прерывала процесс сервера. Это потен-
циально могло привести к возникновению проблем (например, механизму хранения
InnoDB при следующем запуске приходилось выполнять восстановление после аварий-
ного завершения). Начиная с MySQL 3.23.49, Windows ожидает завершения работы сер-
вера MySQL дольше. Если вы обнаружите, что этого недостаточно, будет безопаснее не
запускать сервер MySQL в виде службы. Вместо этого запускайте его из командной
строки и останавливайте с помощью mysqladmin shutdown.
Возможность увеличения времени для ожидания останова службы существует в
Windows 2000 и ХР. Это не работает в Windows NT, где система ожидает останова службы
всего 20 секунд, после чего прерывает процесс. Вы можете увеличить это время ожидания,
открыв редактор системного реестра \winnt\system32\regedt32.exe и изменив значение
WaitToKillServiceTimeout в разделе HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
дерева реестра. Время указывается в миллисекундах (например, значение 120000 соот-
ветствует 120-секундному ожиданию).
Если вы не хотите выполнять mysqld в виде службы, запускайте его в командной
строке. Соответствующие инструкции можно найти в разделе 2.2.1.6.

2.2.1.8. Запуск клиентских программ MySQL в среде Windows


Проверить, функционирует ли сервер MySQL можно с помощью любой из приведен-
ных ниже команд:
С:\> С:\mysql\bin\mysqlshow
С:\> C:\mysql\bin\mysqlshow -u root mysql
С:\> C:\mysql\bin\mysqladmin version status proc
C:\> C:\mysql\bin\mysql test
104 Глава 2. Установка MySQL

Если mysqld медленно реагирует на TCP/IP-соединения клиентских программ в среде


Windows 9x/Me, возможно, существуют проблемы с системой доменных имен (DNS). В
этом случае запустите mysqld с опцией —skip-name-resolve и используйте только
localhost и IP-адреса в столбце Host таблиц привилегий MySQL.
Можно также заставить клиент MySQL подключаться по именованному каналу вме-
сто TCP/IP, указав опцию —pipe или же точку (.) в качестве имени хоста. С помощью
опции —socket указывается имя канала. Для MySQL 4.1 необходимо использовать оп-
цию —ptorocol=PIPE.
Существуют две версии инструмента командной строки MySQL:
Программа Описание
mysql Скомпилирована под Windows, предоставляет ограниченные возможности
по редактированию текста.
mysql с Скомпилирована с помощью компилятора Су gnus GNU с его библиотека-
ми, предоставляет возможности редактирования readline.
Если вы хотите работать с mysql с, у вас должна быть копия библиотеки
cygwinbl9.dll, установленная в таком месте, где mysqlc сможет ее найти. Текущий ди-
стрибутив MySQL содержит эту библиотеку в том же каталоге, где находится mysqlc
(подкаталог bin базового каталога установки MySQL). Если ваш дистрибутив не содер-
жит библиотеки cygwinbl9.dll в каталоге bin, поищите ее в каталоге l i b и скопируйте
ее в системный каталог Windows (\Windows\System или подобный).

2.2.1.9. Сравнение MySQL для Windows и MySQL для Unix


Версия MySQL для Windows в настоящее время доказала свою стабильность. Версия
MySQL для Windows обладает теми же средствами, что и соответствующая версия для
Unix, однако за некоторыми исключениями:
• Windows 95 и потоки. Windows 95 теряет около 200 байт основной памяти при
каждом создании потока. Каждое подключение к MySQL создает новый поток,
поэтому вы не сможете выполнять mysqld в течение длительного времени под
Windows 95, если ваш сервер обслуживает много подключений! Другие версии
Windows этим недостатком не страдают.
• Ограниченное количество портов. Системы Windows имеют около 4000 портов,
доступных клиентским соединениям, и после того, как соединение закрывается,
проходит от двух до четырех минут, прежде чем порт может использоваться зано-
во. В ситуациях, когда клиенты часто подключаются к серверу и отключаются от
него, может случиться, что все доступные порты окажутся занятыми на какое-то
время. При этом MySQL станет недоступным, несмотря на то, что он по-
прежнему будет функционировать. Следует отметить, что порты могут быть заня-
ты и другими приложениями, работающими на данной машине; в этом случае ко-
личество портов, доступных MySQL, еще более уменьшается.
• Параллельное чтение. MySQL зависит от вызовов pread() и pwriteO, чтобы
иметь возможность вперемешку выполнять операторы INSERT и SELECT. В настоя-
щее время мы применяем семафоры (mutexes) для эмуляции pread()/pwrite (). Че-
рез какое-то время мы заменим интерфейс уровня файлов виртуальным интер-
фейсом, дабы можно было использовать интерфейсы readfile()/writefile О в
Windows NT, 2000 и ХР для увеличения скорости. Текущая реализация ограничи-
2.2. Стандартная установка MySQL из бинарного дистрибутива 105

вает количество открытых файлов MySQL числом 1024, а это означает, что вы не
сможете запустить так же много параллельных потоков под NT, 2000 и ХР, как
под Unix.
• Блокирующее чтение. MySQL применяет блокирующее чтение для каждого со-
единения, что приводит к следующим последствиям, если включены соединения
по именованным каналам:
• Соединение не будет автоматически прервано через восемь часов, как это про-
исходит в Unix-версии MySQL.
• Если соединение "зависло", невозможно прервать его без прерывания MySQL.
• mysqladmin k i l l не работает на спящих соединениях.
• mysqladmin shutdown не может остановить сервер, пока есть спящие со-
единения.
Мы планируем решить эти проблемы, когда наши Windows-разработчики подго-
товят хороший "обходной путь".
• ALTER TABLE. Пока выполняется оператор ALTER TABLE, таблица заблокирована от
использования другими потоками. Это обусловлено тем, что в Windows нельзя
удалить файл, который используется другим потоком. Возможно, в будущем мы
найдем, как обойти эту проблему.
• DROP TABLE. Оператор DROP TABLE для таблицы, используемой в таблице MERGE, не
работает под Windows, поскольку MERGE делает отображение таблиц скрытым от
верхнего уровня MySQL. Так как Windows не позволяет удалять открытые файлы,
вам сначала надо сбросить таблицы MERGE (командой FLUSH TABLE), или удалить
таблицу MERGE до выполнения DROP TABLE. Мы исправим это вместе с внедрением
представлений.
• DATA DIRECTORY и INDEX DIRECTORY. Опции DATA DIRECTORY И INDEX DIRECTORY
команды CREATE TABLE в Windows-версии MySQL игнорируются, поскольку
Windows не поддерживает символические ссылки. Эти опции также игнорируют-
ся в системах, имеющих не функциональный вызов r e a l p a t h ().
• DROP DATABASE. Невозможно удалить базу данных, которую использует какой-то
поток.
• Прерывание MySQL из диспетчера задач (Task Manager). Нельзя уничтожить
MySQL с помощью диспетчера задач или утилиты shutdown в Windows 95. Вы
должны это делать командой mysqladmin shutdown.
• Имена, чувствительные к регистру символов. Имена файлов в Windows не
чувствительны к регистру символов, поэтому имена баз данных и таблиц MySQL
в Windows также не чувствительны к регистру. Единственным ограничением яв-
ляется требование, что имя базы данных и таблицы должно указываться в одном и
том же регистре на протяжении всего SQL-оператора.
• Символ 'V для разделения имен каталогов в пути. Имена путей в Windows 95
разделяются символом ' \ \ который интерпретируется MySQL как управляющий.
Если вы используете LOAD DATA INFILE или SELECT.. .INTO OUTFILE, применяйте
разделители V в стиле Unix, например:
mysql> LOAD DATA INFILE 'Ci/tmp/skr.txt' INTO TABLE skr;
mysql> SELECT * INTO OUTFILE 'Cr/tmp/skr.txt f FROM skr;
106 Глава 2. Установка MySQL

В качестве альтернативы можно повторять символ 'V:


mysql> LOAD DATA INFILE 'С:\\tmp\\skr.txt' INTO TABLE skr;
mysql> SELECT * INTO OUTFILE 'C:\\tmp\\skr.txt' FROM skr;
• Проблемы с каналами. Каналы не работают надежно в командной строке
Windows. Если в канал передается символ AZ/CHAR(24), Windows интерпретирует
его как конец файла и прерывает программу. Эта проблема проявляется, когда вы
пытаетесь работать с бинарным журналом следующим образом:
С:\> mysqlbinlog имя_бинарного_журнала | mysql —user=root
Если возникают проблемы при работе с бинарным журналом, и вы предполагаете,
что причина может быть связана с символом AZ/CHAR(24), можете воспользовать-
ся следующим обходным путем:
С:\> mysqlbinlog имя_бинарного_журнала —result-file=/tmp/bin.sql
С:\> mysql —user=root —execute "source /tmp/bin.sql"
Последняя команда также может быть применена для надежного чтения любого
SQL-файла, который содержит бинарные данные.
• Ошибка 'Can't open named pipe9 ('Невозможно открыть именованный канал9).
Если используете сервер MySQL 3.23 в среде Windows NT с новейшими клиент-
скими программами MySQL, может возникнуть ошибка вида:
error 2017: can't open named pipe to host: . pipe...
ошибка 2017: невозможно открыть именованный канал для хоста: . канал...
Это происходит потому, что данная версия MySQL использует в среде Windows
NT именованные каналы по умолчанию. Избежать этой ошибки можно, если ука-
зать опцию —host=localhost в новых MySQL-клиентах, или же создать файл оп-
ций С: \my. cnf, включающий следующую информацию:
[client]
host = localhost
Начиная с версии MySQL 3.23.50, именованные каналы включаются только в том
случае, если mysqld-nt или mysql-max-nt запущены с опцией —enabled-named-pipe.
• Ошибка 'Access denied for user 9 ('Доступ запрещен для пользователя9).
Если вы пытаетесь запустить клиентскую программу MySQL, чтобы подключить-
ся к серверу, работающему на той же машине, и получаете сообщение об ошибке,
подобное: 'Access denied for user 'some-user@unknown' to database 'mysql'',
это означает, что MySQL не может корректно преобразовать имя вашего хоста.
Чтобы исправить подобную ситуацию, потребуется создать файл \windows\hosts,
содержащий такую строку:
127.0.0.1 localhost
Ниже перечислены некоторые открытые задачи для тех, кто пожелает помочь нам
усовершенствовать версию MySQL для Windows:
• Разработать какие-нибудь симпатичные пиктограммы запуска и останова для ус-
тановки MySQL.
• Было бы очень хорошо иметь возможность прерывать mysqld из диспетчера задач
в Windows 95. На сегодня это возможно только командой mysqladmin shutdown.
2.2. Стандартная установка MySQL из бинарного дистрибутива 107

• Перенести библиотеку readline под Windows, чтобы использовать в инструменте


командной строки mysql.
• Версии с графическим интерфейсом стандартных клиентов MySQL (mysql,
mysqldhow, mysqladmin и mysqldump).
• Было бы хорошо, если бы функции чтения и записи сокетов в net. с стали преры-
ваемыми. Это позволило бы прерывать открытые потоки в Windows с помощью
команды mysqladmin k i l l .
• Добавить макросы для использования безопасных в отношении потоков методов
инкремента/декремента, которые предоставляет Windows.

2.2.2. Установка MySQL под Linux


Рекомендуемый способ установки MySQL под Linux предполагает использование RPM-
пакетов. Дистрибутивы MySQL в форме RPM-пакетов в настоящее время собираются в сис-
теме Linux SuSE 7.3, но должны работать в большинстве версий Linux, которые поддержи-
вают rpm и glibc. О том, как получить RPM-пакеты, рассказывается в разделе 2.1.3.
б На заметку!
if*
Л Часто дистрибутивы MySQL в формате RPM-пакетов предлагаются другими поставщиками.
|f Имейте в виду, что они могут отличаться по составу средств и возможностей от тех, что постав-
Щ ляет компания MySQL AB, и поэтому инструкции из настоящего руководства не обязательно
% применимы в отношении их установки. В таки случаях имеет смысл пользоваться инструкциями
fj| поставщиков.

Если у вас возникают проблемы с RPM-файлом (например, если вы получаете сооб-


щение об ошибке наподобие "Sorry, the host 'xxxx' could not be looked up" ("Из-
вините, хост 'хххх' не доступен")), ознакомьтесь с материалами раздела 2.6.1.2.
В большинстве случаев для получения работающей копии MySQL нужно установить
только два пакета - MySQL-server и MySQL-client. Все остальные пакеты для стандарт-
ной установки не обязательны. Если вы хотите запускать сервер MySQL-Max, который
обладает набором дополнительных возможностей, установите дополнительно RPM-
пакет MySQL-Max (см. раздел 4.1.2).
При получении во время установки пакетов MySQL 4.0 сообщения об ошибке, свя-
занной с зависимостями (например, "error: removing these packages would break
dependencies: libmysqlclient.so.10 is needed by . . . " ("ошибка: удаление этих па-
кетов может разрушить зависимости: libmysqlclient.so.10 необходим для ...")), потребу-
ется дополнительно установить пакет MySQL-shared-compat, который включает в себя
две библиотеки общего использования для целей обратной совместимости
(libmysqlclient. so. 12 для MySQL 4.0 и libmysqlclient. so. 10 для MySQL 3.23).
Многие дистрибутивы Linux до сих пор поставляются вместе с MySQL 3.23, и они
обычно динамически связывают приложения, чтобы сэкономить место на диске. Если
эти библиотеки общего использования находятся в другом пакете (например, MySQL-
shared), достаточно просто оставить эти пакеты на месте и только выполнить модерни-
зацию пакетов сервера и клиента MySQL (которые скомпонованы статически и не тре-
буют библиотек общего использования). Для дистрибутивов с библиотеками общего
использования в том же пакете, что и сервер MySQL (например, как в Red Hat Linux), вы
можете либо установить версию 3.23 нашего пакета MySQL-shared, либо воспользоваться
вместо нее пакетом MySQL-shared-compat.
108 Глава 2. Установка MySQL

Доступны следующие RPM-пакеты:


• MySQL-server-ВЕРСИЯ.±386.rpm
Сервер MySQL. Понадобится, если только вы не хотите подключаться к анало-
гичному серверу MySQL, который выполняется на другой машине. Следует отме-
тить, что имена RPM-файлов сервера до версии 4.0.10 имели вид MySQL-
ВЕРСИЯ. i386. rpm, то есть не имели в названии слова -server.
• MySQL-Max-ВЕРСЯЯ. ±386. rpm
Сервер MySQL-Max. Этот сервер обладает дополнительными возможностями, ко-
торых нет в RPM-пакете MySQL-server. Сначала необходимо установить RPM-
пакет MySQL-serve г, поскольку RPM-пакет MySQL-serve r зависит от него.
• MySQL-client-ВЕРСЯЯ.±386.rpm
Стандартные клиентские программы MySQL. Очевидно, что этот пакет устанав-
ливается в любом случае.
• MySQL-bench-ВЕРСЯЯ.±386.rpm
Тесты и испытания производительности. Требуют наличия языка Perl с модулем
DBD::mysql.
• MySQL-devel-ВЕРСЯЯ.±386.rpm
Библиотеки и файлы заголовков, которые понадобятся для компиляции других
MySQL-клиентов, таких как модули Perl.
• MySQL-shared-ВЕРСИЯ.±386.rpm
Этот пакет содержит библиотеки общего использования (libmysqlclient.so*),
которые нужны некоторым языкам и приложениям для динамической загрузки и
взаимодействия с MySQL.
• MySQL-shared-compat-ВЕРСИЯ.±386.rpm
Этот пакет содержит разделяемые (общего использования) библиотеки как для
MySQL 3.23, так и MySQL 4.O. Устанавливайте этот пакет вместо MySQL-shared.
• MySQL-embedded-ВЕРСЯЯ.±386. rpm
Библиотеки встроенного сервера MySQL (начиная с MySQL 4.0).
• MySQL-ВЕРСЯЯ.src.rpm
Здесь содержатся исходные тексты всех перечисленных выше пакетов. Может
также использоваться для повторной сборки RPM-пакетов, ориентированных на
другие архитектуры (например, Alpha или SPARC).
Для просмотра полного списка файлов в RPM-пакете (например, в MySQL-server)
воспользуйтесь следующей командой:
shell> rpm -qpl MySQL-server-B£PCM.i386.rpm
Для выполнения минимальной стандартной установки служат такие команды:
shell> rpm - i MySQL-server-ВЕРСИЯ.i386.rpm
shell> rpm - i MySQL-client-B£POlff.i386.rpm
Чтобы установить только клиентский пакет, выполните приведенную ниже команду:
shell> rpm - i MySQL-client-B£PO^.i386.rpm
2.2. Стандартная установка MySQL из бинарного дистрибутива 109

RPM предоставляет возможность проверить целостность и аутентичность пакетов


перед их установкой. Дополнительную информацию по этой возможности можно найти
в разделе 2.1.4.
Пакет RPM сервера помещает данные в каталог /var/lib/mysql. Кроме того, он соз-
дает в системе пользовательскую учетную запись с именем mysql (если только она не
существовала ранее), от имени которой будет запускаться сервер MySQL, и генерирует
соответствующие записи в / e t c / i n i t . d для автоматического старта сервера во время
загрузки системы. (Это означает, что если у вас на машине присутствовала предыдущая
установка и вы вносили какие-то изменения в сценарии запуска, то их следует скопиро-
вать, чтобы не потерять при новой установке RPM). В разделе 2.4.3 представлена ин-
формация о том, как сервер MySQL может запускаться и останавливаться автоматически
вместе с операционной системой.
Если вы хотите установить RPM-пакет MySQL в систему с более старым дистрибу-
тивом Linux, который не поддерживает инициализационные сценарии в / e t c / i n i t . d
(непосредственно или через символические ссылки), то вам придется создать символи-
ческую ссылку, указывающую на реальное местоположение инициализационных сцена-
риев. Например, если в вашей системе эти сценарии расположены в /etc/rc.d/init.d,
то до начала установки RPM с помощью приведенных ниже команд создайте
/ e t c / i n i t . d как символическую ссылку, указывающую на упомянутое выше местопо-
ложение:
shell> cd /etc
shell> In -s r c . d / i n i t . d .
Однако все современные дистрибутивы Linux уже должны поддерживать новую рас-
кладку каталогов, которая использует /etc/init.d, поскольку того требует совмести-
мость со стандартом LSB (Linux Standard Base).
Если среди RPM-файлов, которые вы устанавливаете, имеется MySQL-server, то по-
сле завершения установки сервер mysqld должен быть поднят и запущен в работу. В та-
ком случае вы немедленно можете приступить к работе с MySQL.
Если что-то пойдет неправильно, вы можете найти более подробную информацию в
разделе, посвященном бинарной инсталляции (см. раздел 2.2.5).
; На заметку!
1;' Пользовательские учетные записи, перечисленные в таблицах привилегий MySQL, изначально
h не имеют паролей. После запуска сервера вы должны установить для них пароли, как описано в
\/ разделе 2.4.

2.2.3. Установка MySQL под Mac OS X


Начиная с MySQL 4.0.11, существует возможность установки MySQL в среде Mac OS
X ("Jaguar"), используя дистрибутив в формате бинарного пакета Mac OS X PKG вместо
старого бинарного формата tar. Помните, что более старые версии Max OS (например,
10.1.x) этим пакетом не поддерживаются.
Пакет находится внутри файла образа диска (.dmg), который вначале необходимо
смонтировать двойным щелчком кнопкой мыши на его пиктограмме в Finder. После это-
го образ будет смонтирован и показано его содержимое.
Информация о получении MySQL приведена в разделе 2.1.3.
110 Глава 2. Установка MySQL

На заметку!
Прежде чем приступать к инсталляции, убедитесь, что все экземпляры серверов MySQL оста-
новлены. Это делается либо с помощью приложения MySQL Manager Application (в Mac OS X
Server), либо по команде mysqladmin shutdown из командной строки.

Чтобы установить пакет MySQL PKG, выполните двойной щелчок на пиктограмме


пакета. Это запустит программу Mac OS X Package Installer, которая проведет через весь
процесс установки MySQL.
Из-за ошибки в установщике пакетов Mac OS X в диалоговом окне выбора диска на-
значения может появиться следующее сообщение:
You cannot install this software on this disk, (null)
Невозможно установить данное программное обеспечение на выбранный диск, (null)
Если такая ошибка произошла, просто щелкните на кнопке Go Back (Назад) один
раз, чтобы вернуться на предыдущий экран. Затем щелкните на кнопке Continue (Про-
должить), чтобы вызвать диалог выбора диска еще раз. На этот раз вы сможете выбрать
диск без проблем. Мы сообщили об этой ошибке в компанию Apple, и они исследуют
проблему.
Пакет Mac OS X PKG MySQL устанавливает себя в каталог /usr/local/mysql-
ВЕРСИЯ и одновременно создает символическую ссылку /usr/local/mysql, указываю-
щую на новое местоположение. Если каталог /usr/local/mysql уже существует, вначале
он переименовывается на /usr/local/mysql.bak. Дополнительно установщик создает
таблицы привилегий в базе данных mysql, выполняя непосредственно после установки
сценарий mysql_install_db.
Расположение файлов после установки такое же, как и при использовании бинарного
дистрибутива в формате tar, - все исполняемые бинарные программы MySQL находятся
в каталоге /usr/local/mysql/bin. Файл сокета MySQL создается по умолчанию как
/tmp/mysql. sock. См. раздел 2.1.5.
Установка MySQL требует наличия учетной записи пользователя Mac OS X с именем
mysql. Пользовательская учетная запись с этим именем должна существовать по умол-
чанию в среде Mac OS X 10.2 и выше.
Если вы работаете с Mac OS X Server, то, скорее всего, версия MySQL уже на нем
присутствует. Версии MySQL, которые поставляются вместе с версиями Mac OS X
Server, перечислены ниже:
Версия Mac OS X Server Версия MySQL
10.2-10.2.2 3.23.51
10.2.3-10.2.6 3.23.53
10.3 4.0.14
10.3.2 4.0.16
Настоящий раздел руководства посвящен только установке официального пакета
MySQL Mac OS X PKG. Ознакомьтесь со справочной информацией Apple об установке
MySQL: запустите приложение "Help View", выберите справку "Mac OS X Server", вы-
полните в ней поиск "MySQL" и прочитайте раздел, озаглавленный "Installing MySQL".
Для предварительно установленной версии MySQL в Mac OS X Server особо обрати-
те внимание на то, что вам нужно запускать mysqld с помощью safejnysqld, а не
mysqldsaf е, если версия MySQL выше 4.0.
2.2. Стандартная установка MySQL из бинарного дистрибутива 111

Если вы ранее работали с пакетом MySQL для Mac OS X от Марка Лайанейджа (Marc
Liyanage) (http://www.entropy.ch), можете просто следовать инструкциям для пакетов с
бинарной раскладкой файлов, описанным на сайте h t t p : //www. entropy. ch.
Если вы обновляете версии 3.23.x MySQL для Mac OS X от Марка или версию
MySQL, которая поставляется с Mac OS X Server, до официального пакета MySQL PKG,
вам потребуется преобразовать существующие таблицы привилегий MySQL в совре-
менный формат, поскольку сейчас появились новые привилегии безопасности (см. раз-
дел 2.5.8).
Если вы предпочитаете, чтобы MySQL автоматически стартовал при запуске систе-
мы, вам нужно будет установить приложение MySQL Startup Item. Начиная с MySQL
4.0.15, эта часть образа инсталляционного диска имеет форму отдельного инсталляцион-
ного пакета. Просто выполните двойной щелчок на пиктограмме MySQLStartupItem.pkg,
после чего следуйте инструкциям по установке.
Обратите внимание на то, что приложение Startup Item нужно установить только од-
нажды! Нет необходимости устанавливать его при каждом обновлении пакета MySQL.
Приложение Startup Item устанавливается в каталог /Library/StartupItems/MySQLCOM.
(До версии MySQL 4.1.2 его местоположением был каталог /Library/StartupItems/MySQL,
что конфликтовало с MySQL Startup Item, установленным с системой Mac OS X Server.)
Установка Startup Item добавляет переменную MYSQLCOM=-YES- в файл конфигурации
системы /etc/hostconfig. Если необходимо отключить автоматический запуск сервера
MySQL, просто измените значение этой переменной на MYSQLCOM=-NO-.
В системе Mac OS X Server установка MySQL по умолчанию использует переменную
MYSQL в файле /etc/hostconfig. Установщик Startup Item от компании MySQL AB от-
ключает эту переменную, устанавливая MYSQL=-NO-. Это позволяет избежать конфликта
с переменной MYSQLCOM, которую использует Startup Item от MySQL AB. Однако это не
останавливает сервер MySQL, если он уже запущен. Останов потребуется выполнить
самостоятельно.
После установки MySQL можно запустить сервер MySQL, выдав в терминальном ок-
не приведенные ниже команды. Вы должны иметь привилегии администратора.
Если есть установленное приложение Startup Item:
shell> sudo /Library/StartupItems/MySQL/MySQL s t a r t
(Enter your password, if necessary)
(Press Control-D or enter "exit" to exit the shell)
(При необходимости введите пароль)
(Нажмите Control-D или введите "exit" для завершения оболочки)
Если же Startup Item нет, воспользуйтесь следующей последовательностью команд:
shell> cd /usr/local/mysql
shell> sudo ./bin/mysqld_safe
(Enter your password, if necessary)
(Press Control-Z)
(При необходимости введите пароль)
(Нажмите Control-Z)
shell> bg
(Press Control-D or enter "exit" to exit the shell)
(Нажмите Control-D или введите "exit" для завершения оболочки)
Теперь у вас можете подключиться к серверу, например, запустив
/usr/local/mysql/bin/mysqld.
112 Глава 2. Установка MySQL

|1 На заметку!
Щ Пользовательские учетные записи, перечисленные в таблицах привилегий MySQL, изначально
§f не имеют паролей. После запуска сервера вы должны установить для них пароли, как описано в
Щ разделе 2.4.

Может возникнуть желание добавить псевдонимы в ресурсный файл оболочки, что-


бы упростить доступ из командной строки к часто используемым программам, таким как
mysql и mysqladmin. Ниже показан синтаксис для оболочки tcsh:
alias mysql /usr/local/mysql/bin/mysql
alias mysqladmin /usr/local/mysql/bin/mysqladmin
А вот синтаксис для оболочки bash:
alias mysql=/usr/local/mysql/bin/mysql
alias mysqladmirWusr/local/mysql/bin/mysqladmin
Еще лучше будет, если добавить путь /usr/local/mysql/bin в переменную окруже-
ния PATH. Например, добавьте следующую строку в файл $HOME/.tcshrc, если использу-
ется командная оболочка tcsh:
setenv PATH ${PATH}:/usr/local/mysql/bin
Если файл .tcshrc в вашем домашнем каталоге не существует, создайте его с помо-
щью текстового редактора.
Если вы обновляете существующую установку, обратите внимание, что установка
нового пакета MySQL PKG не удаляет каталог старой установки. К сожалению, уста-
новщик MacOS X пока не обеспечивает функциональность, необходимую для коррект-
ного обновления ранее установленных пакетов.
Чтобы после установки нового сервера MySQL можно было пользоваться сущест-
вующими базами данных, нужно скопировать содержимое старого каталога данных в
новый. Прежде чем делать это, убедитесь, что ни старый, ни новый сервер не выполня-
ются. После успешного копирования файлов баз данных из старой установки и успеш-
ного запуска нового сервера имеет смысл удалить файлы старой установки, дабы осво-
бодить дисковое пространство. Дополнительно потребуется удалить старую версию ка-
талогов Package Receipt, расположенную в /Library/Receipts/mysql-ВЕРСИЯ.ркд.

2.2.4. Установка MySQL под NetWare


Перенос MySQL в среду NetWare был инициирован самой компанией Novell. Поль-
зователи ОС Novell NetWare 6.5 получают в свое распоряжение встроенный MySQL в
комплекте с автоматической коммерческой лицензией для всех серверов, работающих на
основе упомянутой версии NetWare.
Что касается версии 4.0.11, то сервер MySQL доступен для Novell Netware в форме
бинарного пакета. MySQL для NetWare скомпилирован комбинацией Metrowerks
CodeWarrior for NetWare и специальной кросс-компилирующей версией GNU autotools.
Бинарный пакет для NetWare можно получить с http://dev.mysql.com/downloads/
(см. раздел 2.1.3).
Для нормального функционирования MySQL сервер NetWare должен отвечать сле-
дующим требованиям:
• NetWare версии 6.5 или NetWare версии 6.0 с установленным пакетом поддержки
(Support Pack) версии 3. Он доступен по адресу:
http://support.novell.com/filefinder/13659/index.html
2.2. Стандартная установка MySQL из бинарного дистрибутива 113

• Система должна отвечать требованиям Novell для работы соответствующей вер-


сии NetWare.
• Данные MySQL, равно как и его программы, должны быть установлены на томе
NSS; традиционные тома не поддерживаются.
Для установки MySQL под NetWare потребуется выполнить следующую процедуру:
1. Если вы обновляете предыдущую установку, остановите сервер MySQL. Это де-
лается в серверной консоли с помощью следующей команды:
SERVER: mysqladmin -u root shutdown
2. Зарегистрируйтесь на сервере с клиентской машины, с которой имеется доступ к
местоположению будущей установки MySQL.
3. Распакуйте Zip-файл бинарного пакета на сервер. Не забудьте обеспечить путь
доступа к Zip-файлу. Проще всего распаковать его в SYS: \.
При обновлении предыдущей установки может понадобиться скопировать ката-
лог данных (например, SYS:MYSQL\DATA), а также файл my.cnf, если он настраи-
вался вручную. Затем можно удалить старую копию MySQL.
4. Возможно, вы захотите переименовать каталог, указав для него более понятное и
удобное имя. Мы советуем использовать SYS:MYSQL. Примеры в настоящем руко-
водстве используют это имя для ссылки на каталог установки.
5. В серверной консоли добавьте к пути поиска каталог, в котором содержаться
NLM-модули MySQL, например:
SERVER: SEARCH ADD SYS:MYSQL\BIN
6. Если необходимо, инициализируйте каталог данных и таблицы привилегий, за-
пустив mysqld_install_db в серверной консоли.
7. Запустите сервер MySQL с помощью команды m y s q l s a f e в серверной консоли.
8. Для завершения установки потребуется добавить приведенные ниже команды в
файл autoexec.ncf. Например, если сервер MySQL установлен в каталог
SYS:MYSQL и необходимо, чтобы он запускался автоматически во время старта
системы, добавьте следующие строки:
# S t a r t s t h e MySQL 4 . 0 . x database server
#3апуск сервера баз данных MySQL 4 . 0 . x
SEARCH ADD SYS:MYSQL\BIN
MYSQLD_SAFE
Если вы запускаете MySQL под управлением NetWare 6.0, настоятельно рекомен-
дуем использовать опцию — s k i p - e x t e r n a l - l o c k i n g в командной строке:
# S t a r t s t h e MySQL 4 . 0 . x database server
#3апуск сервера баз данных MySQL 4 . 0 . x
SEARCH ADD SYS:MYSQL\BIN
MYSQLD_SAFE - - s k i p - e x t e r n a l - l o c k i n g
Кроме того, понадобится использовать команды CHECK TABLE и REPAIR TABLE вме-
сто myisamchk, так как myisamchk применяет внешнюю блокировку. Известно, что
внешние блокировки в NetWare 6.0 порождают ряд проблем, которые благопо-
лучно решены в NetWare 6.5.
114 Глава 2. Установка MySQL

mysqldsaf e в NetWare имеет экранное представление. Когда вы выгружаете (ос-


танавливаете) NLM-модуль mysqld_safe, экран по умолчанию не очищается.
Вместо этого он ожидает пользовательского ввода:
*<NLM has terminated; Press any key to close the screen>*
*<NLM завершен; Нажмите любую клавишу для закрытия экрана>*

Если хотите, чтобы NetWare вместо этого закрывал экран автоматически, вос-
пользуйтесь опцией —autoclose, например:
# S t a r t s t h e MySQL 4 . 0 . x d a t a b a s e s e r v e r
#3апуск с е р в е р а б а з данных MySQL 4 . 0 . x
SEARCH ADD SYS:MYSQL\BIN
MYSQLD_SAFE — a u t o c l o s e

Поведение mysqld_safe в среде NetWare описывается далее в разделе 4.1.3.


Если на сервере существовала предыдущая установка MySQL, проверьте наличие
команд запуска MySQL в autoexec.ncf и при необходимости отредактируйте или уда-
лите их.
| На заметку!
;> Пользовательские учетные записи, перечисленные в таблицах привилегий MySQL, изначально
¥ не имеют паролей. После запуска сервера вы должны установить для них пароли, как описано в
С разделе 2.4.

2.2.5. Установка MySQL в других Unix-подобных системах


Этот раздел посвящен установке бинарного дистрибутива MySQL, предназначенного
для разных платформ, в форме сжатых файлов t a r (файлов с расширением .tar.gz).
Подробный список приведен в разделе 2.1.2.5.
Информация о получении дистрибутивов MySQL доступна в разделе 2.1.3.
Бинарные дистрибутивы MySQL в формате t a r имеют имена наподобие mysql-
ВЕРСИЯ-ОС.tar.gz, где ВЕРСИЯ- номер версии (например, 4.0.17), а ОС указывает на тип
операционной системы, для которой предназначен дистрибутив (например, pc-linux-
gnu-i586).
В дополнение к этим общим пакетам, мы также предлагаем бинарные дистрибутивы
в виде пакетов, форматы которых зависят от платформы. В разделе 2.2 можно найти ин-
формацию о том, как их устанавливать.
Для установки бинарного дистрибутива в формате t a r необходимы следующие инст-
рументы:
• Утилита GNU gun zip для распаковки дистрибутива.
• Подходящая программа t a r для распаковки дистрибутива. Хорошо работает, на-
пример, GNU tar. Некоторые операционные системы поставляются вместе с пре-
дустановленными версиями tar, о которых известно, что они имеют определен-
ные проблемы. Например, версии t a r из комплекта Mac OS X и Sun характеризу-
ются сложностями при работе с длинными именами файлов. В среде Mac OS X
можно использовать предустановленную программу gnutar. В других системах с
дефектными утилитами t a r вначале следует установить GNU t a r .
Если вы сталкиваетесь с проблемами, всегда пользуйтесь mysqlbug перед отправкой
вопросов в списки рассылки MySQL. Даже если проблема не вызвана ошибкой,
2.2. Стандартная установка MySQL из бинарного дистрибутива 115

mysqlbug соберет информацию о системе, которая поможет нам решить проблему. Не


используя mysqlbug, вы снижаете вероятность получить решение. Вы найдете mysqlbug в
каталоге bin после распаковки дистрибутива. См. раздел 1.7.1.3.
Базовые команды, которые нужно выполнить для установки и использования бинар-
ного дистрибутива MySQL, выглядят, как показано ниже:
shell> groupadd mysql
shell> useradd -g mysql mysql
shell> cd /usr/local
shell> gunzip < /путь/к/mysql-ВЕРСИЯ-ОС.tar.gz | tar xvf -
shell> In -s полный-путь-к-тузд1-ВЕРСИЯ-0С mysql
shell> cd mysql
shell> scripts/mysql_install_db --user=mysql
shell> chown -R root .
shell> chown -R mysql data
shell> chgrp -R mysql .
shell> bin/mysqld_safe —user=mysql &
Для версий MySQL, предшествующих 4.0, в последней команде замените
bin/mysqld_safе на bin/safe_mysqld.
На заметку!
Эта процедура не устанавливает паролей для пользовательских учетных записей MySQL. После
выполнения описанной процедуры проделайте действия, указанные в разделе 2.4.

Ниже представлена более детальная версия процедуры установки бинарного дистри-


бутива.
1. Добавьте пользователя и группу для запуска mysqld:
shell> groupadd mysql
shell> useradd -g mysql mysql
Эти команды добавляют новую группу mysql и пользователя mysql. Синтаксис
команд groupadd и useradd может слегка отличаться в различных версиях Unix.
Команды также могут иметь названия adduser и addgroup. Вы можете назвать
пользователя и группу как-то иначе вместо mysql. Если это так, в последующих
шагах учтите соответствующие изменения.
2. Выберите каталог для распаковки дистрибутива, и сделайте его текущим. В сле-
дующем примере дистрибутив распаковывается в /usr/local. (Предполагается,
что у вас есть права на создание файлов и подкаталогов внутри /usr/local. Если
каталог защищен, установка должна выполняться от имени пользователя root.)
shell> cd /usr/local
3. Получите дистрибутив с одного из сайтов, перечисленных в разделе 2.1.3. Для те-
кущего выпуска бинарные дистрибутивы для всех платформ собраны из одного и
того же исходного дистрибутива MySQL.
4. Распакуйте дистрибутив, их которого будет создан каталог установки. Затем соз-
дайте символическую ссылку на этот каталог:
shell> gunzip < /путь/к/mysql-ВЕРСИЯ-ОС.tar.gz | tar xvf -
shell> In -s noMHbiu-nyTb-K-mysql-BEPCM-OC mysql
116 Глава 2. Установка MySQL

Команда t a r создает каталог с именем mysql-ВЕРСИЯ-ОС. Команда In создает сим-


волическую ссылку на этот каталог. Это позволит более просто обращаться к ка-
талогу установки - /usr/local/mysql.
В случае применения программы GNU tar нет необходимости отдельно вызывать
gun zip. В данной ситуации можно заменить первую строку следующей альтерна-
тивной командой для распаковки и извлечения дистрибутива:
shell> tar zxvf /путь/к/mysql-ВЕРСИЯ-ОС.tar.gz
5. Перейдите в каталог установки:
s h e l l > cd mysql
В этом каталоге находятся несколько файлов и подкаталогов. Самыми важными
для процесса установки являются подкаталоги bin и scripts:
• bin. Этот каталог содержит программы сервера и клиентские программы. Вы
должны добавить полный путь к этому каталогу в переменную окружения PATH,
чтобы система правильно находила программы MySQL (см. приложение Б).
• scripts. Этот каталог содержит сценарий mysql_install_db, используемый
для инициализации базы данных, которая хранит таблицы привилегий с ин-
формацией о привилегиях доступа к серверу.
6. Если на машине MySQL ранее не устанавливался, потребуется создать таблицы
привилегий:
shell> scripts/mysql_install_db --user=mysql
Если сценарий запускается от имени пользователя root, необходимо использовать
опцию --user, как показано выше. Значение опции должно быть именем пользо-
вателя, который был зарегистрирован на первом шаге. Если команда выполняется
от имени этого пользователя, опцию —user можно не указывать.
Следует обратить внимание на то, что для версий MySQL, предшествующих
3.22.10, mysql_install_db оставляет сервер в работающем состоянии после соз-
дания таблиц привилегий. Теперь это не так. Вам понадобится перезапустить сер-
вер после выполнения оставшихся шагов этой процедуры.
7. Измените владельца бинарных программ на root, а владельца каталога данных -
на пользователя, от имени которого будет запускаться сервер mysqld. Если пред-
положить, что текущим каталогом является установочный (/usr/local/mysql),
команды будут выглядеть так:
shell> chown -R root .
shell> chown -R mysql data
shell> chgrp -R mysql .
Первая команда изменяет владельца файлов на root. Вторая изменяет владельца
каталога данных на mysql. Третья изменяет атрибут принадлежности к группе на
mysql.
8. Если нужно, чтобы сервер MySQL запускался автоматически при загрузке систе-
мы, скопируйте support-files/mysql. server в место, где находятся сценарии за-
пуска системы. Дополнительную информацию по этому поводу можно найти в
самом сценарии support-files/mysql. server, а также в разделе 2.4.3.
2.3. Установка MySQL из исходного дистрибутива 117

9. Если установлены Perl-модули DBI и DBD: :mysql, новые пользовательские учет-


ные записи можно создавать с помощью сценарии bin/mysql_setpermission. Ин-
струкции содержатся в разделе 2.7.
10. Если нужно использовать mysqlaccess, а дистрибутив MySQL размещен в каком-
то нестандартном месте, потребуется изменить местоположение, в котором
mysqlaccess ищет клиент mysql. Отредактируйте сценарий bin/mysqlaccess в
районе 18-й строки. Найдите строку, которая выглядит так:
$MYSQL = Vusr/local/bin/mysql 1 ; # path to mysql executable
# путь к исполняемому файлу mysql
Исправьте путь, чтобы он указывал на реальное местоположение mysql в системе.
Если этого не сделать, то при запуске mysqlaccess вы получите сообщение об
ошибке Broken pipe (разрушенный канал).
После того, как все будет распаковано и установлено, дистрибутив необходимо про-
тестировать.
Запустите сервер MySQL с помощью следующей команды:
shell> bin/mysqld_safe —user=mysql &
Для версий MySQL, предшествующих 4.0, замените в команде bin/mysqld_safe на
bin/safe_mysqld.
Дополнительную информацию о mysqld_safe можно найти в разделе 4.1.3.
|! На заметку!
^ Пользовательские учетные записи, перечисленные в таблицах привилегий MySQL, изначально
Ц не имеют паролей. После запуска сервера вы должны установить для них пароли, как описано в
|< разделе 2.4.

2.3. Установка MySQL из исходного


дистрибутива
Прежде чем приступить к установке исходных текстов, проверьте, доступен ли би-
нарный дистрибутив для вашей платформы и будет он у вас работать. Мы тратим очень
много усилий, чтобы добиться того, чтобы наши программы были собраны наилучшим
образом.
Информация о том, как получить исходный дистрибутив содержится в разделе 2.1.3.
Исходные дистрибутивы MySQL предоставляются в виде tar-архивов и имеют имена
вроде mysql-ВЕРСИЯ, t a r . gz, где ВЕРСИЯ - номер версии, например, 5.0.0-alpha.
Для сборки и установки MySQL из исходных текстов понадобятся:
• Утилита GNU gun zip для распаковки дистрибутива.
• Подходящая программа t a r для распаковки дистрибутива. Хорошо работает, на-
пример, GNU tar. Некоторые операционные системы поставляются вместе с пре-
дустановленными версиями утилиты tar, о которых известно, что они имеют не-
которые проблемы. Например, версии t a r из комплекта Mac OS X и Sun порож-
дают сложности при работе с длинными именами файлов. В Mac OS X можно
воспользоваться предустановленной программой gnutar. В других системах с де-
фектными утилитами t a r сначала потребуется установить GNU tar.
118 Глава 2. Установка MySQL

• Работающий компилятор ANSI C++. Среди компиляторов, о которых известно,


что они работают хорошо, можно отметить: дсс 2.95.2 или более поздний, egcs
1.0.2 или более поздний, egcs 2.91.66, SGI C++ и SunPro C++. Библиотека libg++
не потребуется для дсс. дсс 2.11.x содержит ошибку, которая делает невозможной
компиляцию некоторых абсолютно корректных файлов на C++, например,
sql/sql_base.cc. Если вы располагаете только компилятором дсс 2.77.x, его не-
обходимо обновить, дабы он смог компилировать исходные тексты MySQL, gcc
2.8.1 также известен наличием проблем на некоторых платформах, поэтому его
лучше избегать, особенно ^сли для этой платформы существует какой-нибудь но-
вый компилятор.
• дсс 2.95.2 или более поздней версии рекомендуется для компиляции MySQL
3.23.x.
• Хорошая программа make. GNU make всегда рекомендуется, а зачастую и требует-
ся. В случае возникновения проблем советуем воспользоваться версией GNU make
3.75 или более новой.
Если вы используете достаточно новую версию компилятора дсс, чтобы она понима-
ла опцию —fno-exceptions, очень важно, чтобы вы указывали эту опцию. В противном
случае вы соберете бинарные программы, которые будут произвольно выдавать сбои.
Мы также рекомендуем указывать опции —felide-constructors и — f n o - r t t i вместе с
—fno-exceptions. Если сомневаетесь, воспользуйтесь следующими опциями компи-
ляции:
CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors \
—fno-exceptions -fno-rtti" ./configure \
—prefix=/usr/local/mysql —enable-assembler \
—with-mysqld-ldflags=-all-static
В большинстве систем такой набор опций компилятора позволит получить быстрый
и надежный двоичный код.
Если вы сталкиваетесь с проблемами, всегда пользуйтесь mysqlbug перед отправкой
вопросов в списки рассылки MySQL. Даже если проблема не вызвана ошибкой,
mysqlbug соберет информацию о системе, которая поможет нам решить проблему. Не
используя mysqlbug, вы снижаете вероятность получить решение. Вы найдете mysqlbug в
каталоге bin после распаковки дистрибутива. См. раздел 1.7.1.3.

2.3.1. Обзор установки из исходного дистрибутива


Базовый набор команд, которые нужно выполнить для установки исходного дистри-
бутива:
shell> groupadd mysql
shell> useradd -g mysql mysql
shell> gunzip < mysql-ВЕРСИЯ.tar.gz | tar -xvf -
shell> cd mysql-ВЕРСИЯ
shell> ./configure —prefix=/usr/local/mysql
shell> make
shell> make install
shell> cp support-files/my-medium.cnf /etc/my.cnf
shell> cd /usr/local/mysql
shell> bin/mysql_install_db —user=mysql
2.3. Установка MySQL из исходного дистрибутива 119

shell> chown -R root .


shell> chown -R mysql var
shell> chgrp -R mysql .
shell> bin/mysqld_safe —user=mysql &
Для версий MySQL, предшествующих 4.0, в последней команде замените
bin/mysqld_safe на bin/safe_mysqld.
Если вы работаете с исходным пакетом в формате RPM, запустите такую команду:
s h e l l > rpm --rebuild — c l e a n MySQL-ВЕРСИЯ.src.rpm
Приведенная команда построит бинарный RPM-модуль, который затем можно будет
установить.
% На заметку!
£; Эта процедура не устанавливает паролей для пользовательских учетных записей MySQL. После
и выполнения описанной процедуры проделайте действия, указанные в разделе 2.4.

Ниже представлено более детальное описание процедуры установки исходного дист-


рибутива:
1. Добавьте пользователя и группу для запуска mysqld:
shell> groupadd mysql
shell> useradd -g mysql mysql
Эти команды добавляют новую группу mysql и пользователя mysql. Синтаксис
команд groupadd и useradd может слегка отличаться в различных версиях Unix.
Команды также могут иметь названия adduser и addgroup. Вы можете назвать
пользователя и группу как-то иначе вместо mysql. Если это так, в последующих
шагах учтите соответствующие изменения.
2. Выберите каталог, куда необходимо распаковать дистрибутив, и сделайте его те-
кущим.
3. Получите дистрибутив с одного из сайтов, перечисленных в разделе 2.1.3.
4. Распакуйте дистрибутив в текущий каталог:
shell> gunzip < /путь/'к/mysql-ВЕРСИЯ.tar.gz | tar xvf -
Эта команда создаст каталог с именем mysql-ВЕРСИЯ.
При использовании утилиты GNU t a r отдельного вызова gunzip не требуется. С
помощью следующей команды можно сделать это в один прием:
shell> tar zxvf /путь/к/mysql-ВЕРСИЯ.tar.gz
5. Перейдите в каталог верхнего уровня распакованного дистрибутива:
shell> cd mysql-БЕРСЯЯ
Не забывайте, что конфигурирование и сборка MySQL осуществляется только из
каталога верхнего уровня.
6. Сконфигурируйте выпуск и скомпилируйте все исходные тексты:
shell> ./configure —prefix=/usr/local/mysql
shell> make
При запуске configure можно указывать дополнительные опции. Для получения
списка доступных опций введите команду ./configure --help. В разделе 2.3.2
120 Глава 2. Установка MySQL

обсуждаются некоторые из наиболее часто применяемых опций. Если выполнение


configure завершилось ошибкой, и вы собираетесь отправить сообщение в список
рассылки MySQL с просьбой о помощи, включите в него все строки из
configure.log, которые, по вашему мнению, могут помочь решить проблему.
Кроме того, поместите в сообщение несколько последних строк из configure. При
отправке отчета об ошибке пользуйтесь сценарием mysqlbug. См. раздел 1.7.1.3.
7. Выполните установку дистрибутива:
shell> make install
Если вы хотите настроить файл опций, используйте в качестве шаблона один из
тех, что представлены в каталоге support-files, например:
shell> cp support-files/my-medium.cnf /etc/my.cnf
Возможно, эту команду понадобится запускать от имени пользователя root.
Если вы хотите настроить поддержку таблиц innoDB, отредактируйте файл
/etc/my.cnf, удалив символ # в начале строк опций, которые начинаются с
c
innodb_...', и соответствующим образом изменив значения опций. См. разделы
3.3.2 и 9.4.
8. Перейдите в каталог установки:
shell> cd /usr/local/mysql
9. Если на машине MySQL ранее не устанавливался, потребуется создать таблицы
привилегий:
shell> bin/mysql_install_db —user=mysql
Если сценарий запускается от имени пользователя root, необходимо использовать
опцию —user, как показано выше. Значение опции должно быть именем пользо-
вателя, который был зарегистрирован на первом шаге. Если команда выполняется
от имени этого пользователя, опцию —user можно не указывать.
Следует обратить внимание на то, что для версий MySQL, предшествующих
3.22.10, mysql_install_db оставляет сервер в работающем состоянии после соз-
дания таблиц привилегий. Теперь это не так. Вам понадобится перезапустить сер-
вер после выполнения оставшихся шагов этой процедуры.
10. Измените владельца бинарных программ на root, а владельца каталога данных -
на пользователя, от имени которого будет запускаться сервер mysqld. Если пред-
положить, что текущим каталогом является установочный (/usr/local/mysql),
команды будут выглядеть так:
shell> chown -R root .
shell> chown -R mysql data
shell> chgrp -R mysql .
Первая команда изменяет владельца файлов на root. Вторая изменяет владельца
каталога данных на mysql. Третья изменяет атрибут принадлежности к группе на
mysql.
11. Если нужно, чтобы сервер MySQL запускался автоматически при загрузке систе-
мы, скопируйте support-files/mysql. server в место, где находятся сценарии за-
2.3. Установка MySQL из исходного дистрибутива 121

пуска системы. Дополнительную информацию по этому поводу можно найти в


самом сценарии support-files/mysql. server, а также в разделе 2.4.3.
12. Если установлены Perl-модули DBI и DBD::mysql, новые пользовательские учет-
ные записи можно создавать с помощью сценарии bin/mysql_setpermission. Ин-
струкции содержатся в разделе 2.7.
После того, как все будет распаковано и установлено, нужно протестировать дистри-
бутив.
Запустите сервер MySQL с помощью следующей команды:
shell> bin/mysqld_safe —user=mysql &
Для версий MySQL, предшествующих 4.0, замените в команде bin/mysqld_safe на
bin/safe_mysqld.
Если выполнение этой команды немедленно прерывается с выдачей сообщения
raysqld ended (mysqld завершен), некоторую информацию, касающуюся причин, можно
найти в файле host_name. err, расположенном в каталоге данных.
Дополнительные сведения о mysqld_safe представлены в разделе 4.1.3.
f| На заметку!
|| Пользовательские учетные записи, перечисленные в таблицах привилегий MySQL, изначально
f* не имеют паролей. После запуска сервера вы должны установить для них пароли, как описано в
Ь разделе 2.4.

2.3.2. Типичные опции сценария configure


Сценарий configure обеспечивает богатые возможности управления настройкой ис-
ходного дистрибутива MySQL. Обычно это делается через опции командной строки во
время его запуска. В некоторой степени им можно также управлять через переменные
окружения (см. приложение Б). Получить полный список опций, которые поддерживает
configure, можно следующим образом:
shell> ./configure —help
Ниже описаны наиболее часто используемые опции configure.
• Для того чтобы скомпилировать только клиентские программы и библиотеки, без
сервера, используйте опцию --without-server.
Если у вас нет компилятора C++, mysql не скомпилируется (это единственная
клиентская программа, которой требуется компилятор C++). В этом случае може-
те удалить из configure строки, проверяющие наличие компилятора C++, и затем
опять запустить его с опцией —without-server. На шаге компиляции он опять
попытается выполнить сборку mysql, но вы можете игнорировать любые сообще-
ния, касающиеся mysql.ее. (Если программа make остановится, попробуйте запус-
тить ее с ключом -к, который указывает, что сборку нужно продолжать, даже если
встречаются ошибки.)
• Если требуется собрать библиотеку встроенного MySQL (libmysqld.a), исполь-
зуйте опцию —with-embedded-server.
• Если вы не хотите, чтобы журнальные файлы и каталоги данных находились в
/usr/local/var, используйте configure следующим образом:
shell> ./configure —prefix=/usr/local/mysql
122 Глава 2. Установка MySQL

shell> ./configure --prefix=/usr/local \


--localstatedir=/usr/local/mysql/data
Первая команда изменяет префикс установки таким образом, чтобы все, что должно
было копироваться в каталог /usr/local, помещалось в каталог /usr/local/mysql.
Вторая команда сохраняет префикс установки, но изменяет местоположение
каталога данных, которым по умолчанию является / u s r / l o c a l / v a r , на
/usr/local/mysql/data. После того, как вы скомпилируете MySQL, эти значения
можно изменить в файле опций (см. раздел 3.3.2).
• Если вы работаете в среде Unix и желаете, чтобы сокет MySQL располагался в
месте, отличном от принятого по умолчанию (/tmp или /var/run), запустите ко-
манду configure так, как показано ниже:
shell> ./configure \
—with-unix-socket-path=/usr/local/mysql/tmp/mysql.sock
Имя файла сокета должно содержать полный путь. Вы также можете позже изме-
нить местоположение mysql. sock в файле опций (см. раздел А.4.5).
• Если требуется скомпилировать программы, связанные статически (например,
чтобы получить более быстрый бинарный дистрибутив или обойти проблемы, ха-
рактерные для некоторых версий Red Hat Linux), запускайте configure следую-
щим образом:
shell> ./configure —with-client-ldflags=-all-static \
—with-mysqld-ldflags=-all-static
• Если вы пользуетесь gcc и не имеете установленных библиотек libg++ или
libstdc++, можете указать configure, что в качестве компилятора C++ должен
использоваться gcc:
shell> CC=gcc CXX=gcc ./configure
При использовании gcc в качестве компилятора C++, он не будет пытаться вы-
полнять связывание с библиотеками libg++ и libstdc++. Это может оказаться по-
лезным, даже если у вас эти библиотеки установлены, поскольку некоторые их
версии могут в будущем послужить причиной возникновения странных проблем у
пользователей MySQL.
В следующем списке перечислены некоторые компиляторы и обычно используе-
мые с ними значения переменных окружения:
• gcc 2.7.2:
CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors"
• egcs 1.0.3a:
CC=gcc CXX=gcc CXXFLAGS="-03 -felide-constructors \
-fno-exceptions -fno-rtti"
• gcc 2.95.2:
CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-03 -mpentiumpro \
-felide-constructors -fno-exceptions -fno-rtti"
• pgcc 2.90.29 или более новые:
CFLAGS="-03 -mpentiumpro -mstack-align-double" CXX=gcc \
2.3. Установка MySQL из исходного дистрибутива 123

CXXFLAGS="-O3 -mpentiumpro -mstack-align-double \


-felide-constructors -fno-exceptions -fno-rtti"
Во многих случаях можно получить достаточно оптимальный код MySQL, при-
меняя опции из приведенного списка и добавляя к строке configure еще и такие
опции:
—prefix=/usr/local/mysql —enable-assembler \
—with-mysqld-ldflags=-all-static
Другими словами, полная строка запуска configure должна принять вид, подоб-
ный показанному ниже, для всех последних версий дсс:
CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro \
-felide-constructors -fno-exceptions - f n o - r t t i " ./configure \
—prefix=/usr/local/mysql —enable-assembler \
—with-mysqld-ldflags=-all-static
Все бинарные дистрибутивы, доступные на http://www.mysql.com, скомпилиро-
ваны с полной оптимизацией и должны превосходно работать у большинства
пользователей (см. раздел 2.1.2.5). Существуют некоторые установки конфигура-
ции, которые помогут собрать еще более быстрые двоичные программы, однако
они ориентированы только на опытных пользователей (см. раздел 6.5.3).
Если сборка завершилась ошибкой, связанной с тем, что ваш компилятор или
компоновщик не в состоянии создать библиотеку общего использования
l i b m y s q l c l i e n t . s o . # (где ' # ' - номер версии), эту проблему можно обойти, ука-
зав configure опцию —disable-shared. В этом случае configure не будет созда-
вать библиотеку общего использования l i b m y s q l c l i e n t . s o . #.
• Можно сконфигурировать MySQL так, чтобы он не использовал значения столб-
цов по умолчанию (DEFAULT) для тех из них, которым запрещено иметь значения
NULL (см. раздел 1.8.6.2):
s h e l l > CXXFIAGS=-DDONTJJSEJ)EFAULT_FIELDS ./configure
Эффект от применения этого флага состоит в том, что любой оператор INSERT за-
вершится ошибкой, если в нем явно не заданы значения для всех столбцов с атри-
бутами NOT NULL.
• По умолчанию MySQL использует набор символов l a t i n l (ISO-8859-1). Для из-
менения набора символов по умолчанию служит опция - - w i t h - c h a r s e t :
shell> ./configure —with-charset=Ha6op
При этом набор может принимать одно из следующих значений: big5, cpl251,
ср1257, czech, danish, dec8, dos, eucjtr, gb2312, gbk, germanl, hebrew, hp8,
hungarian, koi8_ru, koi8_ukr, l a t i n l , Iatin2, s j i s , swe7, tis620, ujis, usa7 и
winl251ukr. За дополнительной информацией обращайтесь в раздел 4.7.1.
Также можно задать способ сопоставления строк по умолчанию. По умолчанию
MySQL использует сопоставление строк l a t i n l _ s w e d i s h _ c i . Для изменения этого
применяется опция — with-collation:
shell> ./configure —with-collation=collation
Чтобы изменить одновременно и набор символов и способ сопоставления, укажи-
те обе опции —with-charset и —with-collation. Порядок сопоставления должен
124 Глава 2. Установка MySQL

быть разрешенным для данного набора символов. (С помощью команды SHOW


COLLATION можно просмотреть, какие порядки сопоставления для каких наборов
символов допустимы.)
Если вас интересует преобразование набора символов между клиентом и серве-
ром, ознакомьтесь с оператором SET CHARACTER SET. Эта тема обсуждается в кни-
ге "MySQL. Справочник по языку".
| Внимание!
§} Если вы измените набор символов после создания любых таблиц, то для каждой из них потребу-
Щ ется выполнить myisamchk - r -q —set-character-set=Ha6op. В противном случае индек-
§| сы могут быть отсортированы неправильно. (Это может случиться в ситуации, когда вы устано-
|| вили MySQL, создали какие-то таблицы, затем переконфигурировали MySQL для применения
|| другого набора символов и установили повторно.)

Указывая для configure опцию — with-extra-charsets=Cn#COiC, можно опреде-


лить, с поддержкой каких дополнительных наборов символов должен быть ском-
пилирован сервер. Здесь СПИСОК - это либо список наборов символов, разделен-
ных пробелами, либо complex, что означает включение всех наборов символов,
которые не могут быть загружены динамически, либо a l l - включение всех набо-
ров символов в бинарный код.
• Чтобы сконфигурировать MySQL с отладочной информацией, укажите опцию
—with-debug:
shell> ./configure —with-debug
Это заставит компоновщик включить в программу безопасный распределитель
памяти, который может обнаруживать некоторые ошибки и генерировать сообще-
ния о том, что происходит.
• Если ваши клиентские программы используют потоки, вы также должны скомпи-
лировать версию, безопасную в отношении потоков, клиентской библиотеки
MySQL, указав опцию конфигурации — enable-thread-safe-client. В результате
будет создана библиотека libmysqlclientr, с которой можно будет компоновать
потоковые приложения.
• Описание опций, специфичных для отдельных платформ, можно найти в части
настоящего руководства, посвященной конкретным системам (см. раздел 2.6).

2.3.3. Установка из исходного дерева разработки


| Внимание!
Ц Этот раздел имеет смысл читать только в том случае, если вы хотите оказать нам помощь в тес-
|| тировании нового кода. Если вам нужно только получить MySQL для запуска в своей системе,
|; выгружайте стандартный дистрибутив выпуска (бинарный или исходный).

Для получения последнего дерева исходных текстов потребуется выполнить сле-


дующие шаги:
1. Загрузите BitKeeper с http://www.bitmover.com/cgi-bin/download.cgi. Для дос-
тупа к нашему репозиторию понадобится BitKeeper 3.0 или более новый.
2. Установите его в соответствии с инструкциями.
2.3. Установка MySQL из исходного дистрибутива 125

3. После установки BitKeeper перейдите в каталог, из которого вы собираетесь рабо-


тать, а затем воспользуйтесь одной из приведенных ниже команд для загрузки
ветви выбранной версии MySQL.
Для выгрузки старой ветви 3.23:
shell> bk clone bk://mysql.bkbits.net/mysql-3.23 mysql-3.23
Для выгрузки стабильной ветви 4.0:
shell> bk clone bk://mysql.bkbits.net/mysql-4.0 mysql-4.0
Для выгрузки ветви 5.0, находящейся в стадии разработки:
shell> bk clone bk://mysql.bkbits.net/mysql-5.0 mysql-5.0
В представленных примерах исходные деревья расположатся соответственно в
подкаталогах mysql-3.23/, mysql-4.0/, mysql-4.1/ и mysql-5.0/ текущего ката-
лога.
Если вы защищены брандмауэром и имеете возможность работать только через
HTTP-соединения, можно взаимодействовать с BitKeeper по протоколу HTTP.
Если вам необходимо использовать прокси-сервер, установите переменную окру-
жения http_proxy, чтобы она указывала на него:
shell> export httpjproxy="http://your.proxy,server:8080/"
Теперь просто замените bk: // на http: //, например:
shell> bk clone http://mysql.bkbits.net/mysql-4.! mysql-4.1
Начальная загрузка дерева исходных текстов может занять довольно длительное
время, в зависимости от скорости вашего соединения. В общем, наберитесь тер-
пения.
4. Вам понадобятся GNU make, autoconf 2.53 (или более новый), automake 1.5,
libtool 1.4 и m4 для запуска следующего набора команд. Несмотря на то, что
многие операционные системы уже поставляются со своими собственными реали-
зациями make, высока вероятность того, что компиляция прервется со странными
сообщениями об ошибках. Поэтому мы настоятельно рекомендуем пользоваться
вместо них программой GNU make (иногда называемой gmake).
К счастью, многие операционные системы уже поставляются с заранее установ-
ленным набором инструментов GNU, либо же включают его инсталляционные
пакеты. В любом случае, их также можно загрузить со следующих сайтов:
• http://www.gnu.org/software/autoconf/
• http://www.gnu.org/software/automake/
• http://www.gnu.org/software/libtool/
• http://www.gnu.org/software/m4/
• http://www.gnu.org/software/make/
Если вы пытаетесь сконфигурировать MySQL 4.1 или более позднюю версию, вам
понадобится также GNU bison 1.75 или выше. Старые версии bison могут выда-
вать ошибку:
sql_yacc.yy:#####: fatal error: maximum table size (32767) exceeded
sql_yacc.yy:#####; критическая ошибка: превышен максимальный размер
таблицы (32767)
126 Глава 2. Установка MySQL

^ Примечание!
/Л На самом деле максимальный размер таблицы не превышен, а сообщение вызвано ошибкой в
/ старых версиях bison.
Версии MySQL, предшествующие 4.1, могут также компилироваться с другими
реализациями уасс (например, BSD yacc 91.7.30). Для более новых версий необ-
ходим GNU bison.
В приведенном примере представлена типичная последовательность команд, не-
обходимая для конфигурирования исходного дерева. Первая команда cd меняет
текущий каталог на корневой каталог дерева. Замените при необходимости имя
каталога mysql-4.0 в аргументе команды.
shell> cd mysql-4.0
shell> bk -r edit
shell> aclocal; autoheader; autoconf; automake
shell> (cd innobase; aclocal; autoheader; autoconf; automake)
shell> (cd bdb/dist; sh s_all)
shell> ./configure # Добавьте здесь необходимые опции
shell> make
Командные строки, изменяющие текущий каталог на innobase и bdb/dist, нужны
для конфигурирования механизмов хранения innoDB и Berkley DB (BDB). Если вам
не нужна поддержка InnoDB и BDB, эти строки можно опустить.
Если вы получите какие-то непонятные сообщения об ошибках на этой стадии,
проверьте, установлена ли у вас библиотека libtool.
Коллекция наших стандартных конфигурационных сценариев находится в подка-
талоге BUILD/. Возможно, вы сочтете более удобным запускать сценарий
BUILD/compile-pentium-debug вместо приведенной выше последовательности
команд. Для компиляции на другой архитектуре исправьте сценарий, удалив все
флаги, специфичные для процессора Pentium.
5. Когда сборка будет завершена, введите команду make i n s t a l l . Будьте осторожны
с этим на рабочей машине. Так вполне можно перезаписать актуальную установку
сервера. Если у вас на машине есть другой установленный экземпляр MySQL, ре-
комендуется запускать ./configure с другими значениями опций —prefix,
--with-tcp-port и --unix-socket-path, нежели те, которые использовались для
вашего рабочего сервера.
6. Интенсивно поработайте с новой установкой, попытайтесь вызвать сбой новых
средств. Начните с запуска make test.
7. Если вы дошли до стадии make и дистрибутив не компилируется, пришлите сооб-
щение об этом в нашу базу ошибок на h t t p : //bugs .mysql. com. Если вы установи-
ли новейшие версии необходимых инструментов GNU и они терпят крах при по-
пытке обработать наши конфигурационные файлы, сообщите и об этом тоже. Од-
нако если вы запускаете команду aclocal и получаете в ответ not found (не
найдена) или какую-то подобную ошибку, не уведомляйте об этом. Вместо этого
убедитесь, что все необходимые инструменты установлены, а значение перемен-
ной окружения PATH задано таким образом, что командный интерпретатор может
их найти.
2.3. Установка MySQL из исходного дистрибутива 127

8. После начальной команды bk clone, с помощью которой вы получите дерево ис-


ходных текстов, периодически выполняйте bk pull, чтобы получать обновления.
9. Вы можете просмотреть историю изменений в дереве с помощью bk revtool. Ес-
ли вы обнаружите какие-то незначительные расхождения или код, который вызо-
вет вопросы, не стесняйтесь присылать сообщения в список рассылки MySQL
internals (см. раздел 1.7.1.1). Кроме того, если у вас появились лучшие идеи от-
носительно того, как реализовать что-то, присылайте сообщение туда же, прило-
жив к нему обновление, bk dif fs сгенерирует для вас обновление после того, как
вы внесете изменения в копию исходного кода на своей машине. Если у вас нет
времени воплотить свою идею в коде, просто пришлите исчерпывающее описание.
10. BitKeeper обладает неплохой утилитой справки, к которой можно обратиться с
помощью команды bk helptool.
И.Учтите, что любые фиксации кода (выполненные по команде bk ci или bk
citool) вызовут автоматическую отправку сообщения о внесенных в код измене-
ниях в список рассылки MySQL internals, в точности так, как происходит обыч-
ное подтверждение openloging.org, даже если изменяются только комментарии.
Вообще говоря, у вас нет необходимости выполнять фиксацию (поскольку обще-
доступный репозиторий не позволяет выполнять bk push). Вместо этого исполь-
зуйте метод bk dif f s, описанный выше.
Вы также можете просматривать наборы изменений кода, комментарии и сам исход-
ный текст в онлайновом режиме. Например, чтобы просмотреть эту информацию для
MySQL 4.1, зайдите на http://mysql.bkbits.net: 8080/mysql-4.1.
Справочное руководство находится в отдельном дереве, которое может быть загру-
жено с помощью следующей команды:
shell> bk clone bk://mysql.bkbits.net/mysqldoc mysqldoc
Существуют также общедоступные деревья BitKeeper для приложений MySQL
Control Center (Центр управления MySQL) и Connector/ODBC. Они также доступны для
загрузки.
Чтобы загрузить MySQL Control Center, введите команду:
shell> bk clone http://mysql.bkbits.net/mysqlcc mysqlcc
Для загрузки Connector/ODBC воспользуйтесь командой:
shell> bk clone http://mysql.bkbits.net/myodbc3 myodbc3

2.3.4. Решение проблем компиляции MySQL


Все программы MySQL компилируются в системах Linux и Solaris с использованием
компилятора дсс без каких-либо предупреждений и ошибок. В других системах во время
компиляции могут возникать некоторые предупреждения из-за разницы во включаемых
системных файлах заголовков. В разделе 2.3.5 приведена информация о предупреждени-
ях, которые могут возникать при использовании потоков MIT-pthreads. О других про-
блемах компиляции рассказывается ниже.
Решение многих проблем может предполагать переконфигурирование. Если в этом
есть необходимость, примите во внимание следующие моменты:
• Если configure запускается после того, как уже запускался, он может использо-
вать информацию, собранную во время предыдущего вызова. Эта информация
128 Глава 2. Установка MySQL

помещается в файл config. cache. Когда сценарий configure стартует, он выпол-


няет поиск этого файла. Если файл найден, configure читает его содержимое,
предполагая, что собранная ранее информация корректна. Это предположение
ошибочно, если необходимо выполнить переконфигурирование.
• Каждый раз после запуска configure необходимо снова запустить make для пере-
компиляции. Однако имеет смысл удалить старые объектные файлы, оставшиеся
после предыдущей сборки, прежде всего потому, что они были скомпилированы с
использованием других конфигурационных опций.
Для предотвращения использования устаревшей конфигурационной информации или
объектных файлов, выполняйте приведенные ниже команды перед каждым перезапус-
ком configure:
shell> rm config.cache
shell> make clean
В качестве альтернативы можно запустить make distclean.
В следующем списке перечислены проблемы, которые возникают наиболее часто во
время компиляции MySQL.
• Если во время компиляции s q l y a c c . c c вы получаете сообщения об ошибках
вроде тех, что показаны ниже, это означает, что, скорее всего, превышен лимит
использования памяти или пространства подкачки:
Internal compiler error: program cclplus got fatal signal 11
Внутренняя ошибка компилятора: программа cclplus получила фатальный
сигнал 11
Out of v i r t u a l memory
Яе хватает виртуальной памяти
Virtual memory exhausted
Виртуальная память исчерпана
Проблема состоит в том, что дсс требует огромного объема памяти для компиля-
ции sql_yacc.cc со встроенными функциями. Попробуйте запустить configure с
опцией —with-low-memory:
shell> ./configure —with-low-memory
Эта опция требует также дополнительного указания опции —f no-inline, если вы
применяете дсс, и -00 - если другой компилятор. Стоит попробовать задать
—with-low-memory, даже если у вас много памяти и пространства подкачки, и вы
уверены, что не столкнетесь с упомянутой проблемой. Возникновение этой про-
блемы наблюдалось даже на машинах с большим объемом ресурсов, при этом
указание опции —with-low-memory обычно решало ее.
• По умолчанию configure выбирает в качестве имени компилятора с++, который
выполняет компоновку с -lg++. Если вы используете дсс, это поведение может
привести к проблемам во время конфигурирования:
configure: error: installation or configuration problem:
C++ compiler cannot create executables.
configure: ошибка: проблема установки или конфигурации:
компилятор C++ не может создавать исполняемые файлы.
2.3. Установка MySQL из исходного дистрибутива 129

Вы также можете столкнуться с проблемами во время компиляции, которые свя-


заны с g++, libg++ или libstdc++.
ОДНОЙ ИЗ причин возникновения этих проблем может быть то, что у вас может от-
сутствовать д++, либо у вас имеется д++, но нет libg++ или libstdc++. Просмот-
рите файл conf ig. log. Он должен содержать точное объяснение причины, почему
компилятор C++ не работает. Для обхода этих проблем можно выбрать дсс в ка-
честве компилятора C++. Попробуйте присвоить переменной окружения СХХ зна-
чение дсс -03:
shell> CXX="gcc -03" ./configure
Это работает потому, что дсс компилирует исходные тексты на C++ так же, как и
д++, но не выполняет по умолчанию компоновку с библиотеками libg++ и
libstdc++.
Другой способ решения этой проблемы предполагает установку g++, libg++ и
libstdc++. Однако, м ы рекомендуем отказаться от применения библиотек libg++
и libstdc++ вместе с M y S Q L , поскольку это только увеличивает размер mysqld,
не принося какой-либо выгоды. Некоторые версии этих библиотек в прошлом
служили причиной непонятных проблем у пользователей M y S Q L .
Применение дсс в качестве компилятора C + + также необходимо, если вы хотите
скомпилировать M y S Q L с поддержкой функциональности R A I D и вы используете
дсс версии 3 и выше. Если при конфигурации с опцией —width-raid на стадии
компоновки вы получаете сообщения об ошибках вроде тех, что приведены выше,
попробуйте использовать дсс в качестве компилятора C++, указав его в перемен-
ной окружения СХХ:
дсс -03 -DDBUG_OFF -rdynamic -о isamchk isamchk.o sort.о libnisam.a
../mysys/libmysys.a ../dbug/libdbug.a ../strings/libmystrings.a
-Ipthread -lz -lcrypt -lnsl -lm -lpthread
../mysys/libmysys.a(raid.o)(.text+0x79): In function
"my_raid_createf:: undefined reference to "operator new(unsigned)'
../mysys/libmysys.a(raid.o)(.text+Oxdd): In function
4
my_raid_create':: undefined reference to "operator delete(void*)'
../mysys/libmysys.a(raid.o)(.text+0xl29): In function
"my_raid_openf:: undefined reference to "operator new(unsigned)'
../mysys/libmysys.a(raid.o)(.text+0xl89): In function
"my raid open1:: undefined reference to "operator delete(void*)'
../mysys/libmysys.a(raid.o)(,text+0x64b): In function
"my_raid_close':: undefined reference to "operator delete(void*)'
collect2: Id returned 1 exit status
• Если компиляция прерывается с выдачей сообщений об ошибках, которые пока-
заны ниже, потребуется обновить свою версию make до G N U make.
making all in mit-pthreads
make: Fatal error in reader: Makefile, line 18:
Badly formed macro assignment
или
make: file "Makefile' line 18: Must be a separator (:
или
pthread.h: No such file or directory
130 Глава 2. Установка MySQL

Известно, что в средах Solaris и FreeBSD приходится сталкиваться с некоторыми


проблемами, связанными с make.
С другой стороны, программа GNU make версии 3.75 зарекомендовала себя доста-
точно хорошо.
• Если вы хотите определить флаги для использования с компиляторами С и C++,
добавляйте их к переменным окружения CFLAGS и CXXFLAGS. Таким же способом
можно задать имена компиляторов - через переменные СС и СХХ. Например:
shell> CC=gcc
shell> CFLAGS=-O3
shell> CXX=gcc
shell> CXXFLAGS=-O3
shell> export CC CFLAGS CXX CXXFLAGS
В разделе 2.1.2.5 представлен список флагов, применяемых в различных системах.
• Если вы получите сообщение об ошибке, подобное показанному ниже, вам при-
дется обновить компилятор:
client/libmysql.c:273: parse error before N attribute '
client/libmysql.с:273: ошибка анализа перед ч атрибут '
Известно, что дсс 2.8.1 работает, но м ы рекомендуем вместо него пользоваться
дсс 2.95.2 или egsc 1.0.3а.
• Если во время компиляции mysqld вы получаете ошибки вроде приведенных ни-
же, это значит, что configure не может корректно распознать последний аргумент
accept(), getsockname() или getpeername():
схх: Error: mysqld.cc, line 645: In this statement, the referenced
type of the pointer value ''length1' is ''unsigned long 1 1 ,
which is not compatible with ''int1'.
new_sock = accept(sock, (struct sockaddr *)&cAddr, &length);
Чтобы исправить это, отредактируйте файл config.h (сгенерированный
configure). Найдите следующие строки:
/* Define as the base type of the last arg to accept */
/* Определить в качестве базового типа для последнего аргумента */
#define SOCKET__SIZE_TYPE XXX
Измените XXX на s i z e t или int, в зависимости от вашей операционной системы.
(Помните, что вам придется это делать после каждого запуска configure, по-
скольку этот сценарий все время перезаписывает config.h.)
• Файл sql_yacc.cc генерируется из sql_yacc.yy. Обычно процесс сборки не нуж-
дается в пересоздании sqlyacc.ee, потому что MySQL поставляется с готовой
копией. Однако если вам понадобится пересоздать его, вы можете столкнуться с
такой ошибкой:
"sql_yacc.yy", line xxx f a t a l : default action causes p o t e n t i a l . . .
Это знак того, что ваша версия уасс дефектна. Возможно, потребуется установить
bison (версию уасс от GNU) и пользоваться ею.
2.3. Установка MySQL из исходного дистрибутива 131

• В среде Debian Linux 3.0 вам нужно установить gawk вместо поставляемой по
умолчанию mawk, если вы хотите компилировать MySQL 4.1 и выше с поддержкой
Berkley DB.
• Если необходимо отлаживать mysqld или клиенты MySQL, запустите configure с
опцией —with-debug, затем перекомпилируйте и скомпонуйте ваши программы с
новой клиентской библиотекой.
• Если во время компиляции в среде Linux (например, SuSE Linux 8.1 или Red Hat
Linux 7.3) выдаются сообщения об ошибках, похожие на следующие:
libmysql.c:1329: warning: passing arg 5 of 4 gethostbyname_r' from
incompatible pointer type
libmysql.c:1329: too few arguments to function 4 gethostbyname_r'
libmysql.c:1329: warning: assignment makes pointer from integer
without a cast
make[2]: *** [libmysql.lo] Error 1
то это вызвано тем, что по умолчанию сценарий configure пытается определить
правильное число аргументов, используя компилятор C++ GNU g++. Эта проверка
дает неверные результаты, если не установлен д++. Существуют два способа
обойти эту проблему:
• Необходимо убедиться, что д++ из комплекта GNU C++ установлен. В некото-
рых дистрибутивах Linux требуемый пакет называется дрр, в других - дсс-с++.
• Следует использоваться дсс в качестве компилятора C++, следующим образом
установив значение переменной окружения СХХ:
export CXX="gcc"
Не забудьте после этого перезапустить configure.

2.3.5. Замечания по поводу потоков MIT-pthreads


Этот раздел касается некоторых вопросов, связанных с использованием потоков MIT-
pthreads.
В операционных системах Linux вы не должны использовать потоки MIT-p threads.
Вместо них нужно работать с установленными реализациями LinuxThreads. См. раздел
2.6.1.
Если ваша система не обладает встроенной поддержкой потоков, вам придется вы-
полнять сборку MySQL с использованием пакета MIT-p threads. Это касается старых сис-
тем FreeBSD, SunOS 4.x, Solaris 2.4 и предшествующих версий, а также ряда других сис-
тем (см. раздел 2.1.1).
Начиная с MySQL 4.0.2, MIT-pthreads больше не являются частью исходных
дистрибутивов. Если вам нужен этот пакет, его придется загрузить отдельно -
http://www.mysql.com/Downloads/Contrib/pthreads-l_60_beta6-mysql.tar.gz.
После загрузки извлеките исходный архив в корневой каталог исходных текстов
MySQL. При этом будет создан новый подкаталог с именем m i t - p t h r e a d s .
• В большинстве систем можно принудительно использовать MIT-pthreads, запус-
тив configure с опцией —with-mit-pthreads:
shell> ./configure —with-mit-threads
132 Глава 2. Установка MySQL

Сборка в каталогах, не относящихся к исходному дистрибутиву, не поддержива-


ется при использовании MIT-pthreads, поскольку мы стремимся минимизировать
изменения, вносимые в этот код.
• Проверка того, где должны использоваться MIT-pthreads, происходит только во
время процесса конфигурирования, имеющего отношение к коду сервера. Если вы
сконфигурировали дистрибутив с опцией —without-server, чтобы собирать
только клиентский код, программы-клиенты не знают, где использовать MIT-
pthreads и будут по умолчанию открывать соединения через Unix-сокеты. А так
как файлы Unix-сокетов не работают под MIT-pthreads на некоторых платформах,
это означает, что вам придется запускать клиентские программы с ключами -h
или — h o s t .
• Когда MySQL компилируется с MIT-pthreads, системная блокировка по умол-
чанию отключается из соображений, связанных с производительностью. Вы
можете заставить сервер применять системную блокировку с помощью опции
—external-locking. Это может понадобиться только в случае, если вы хотите за-
пускать два сервера MySQL для одних и тех же файлов данных, что не рекомен-
дуется.
• Иногда вызов bind () pthread-потока не может связаться с сокетом без сообщений
об ошибках (по крайней мере, в среде Solaris). В результате все попытки соедине-
ния с сервером оказываются неудачными:
s h e l l > mysqladmin version
mysqladmin: connect to server at ? l failed;
e r r o r : 'Can't connect to mysql server on localhost (146)'
Решением может быть останов и перезапуск сервера mysqld. У нас это получа-
лось, только если сервер останавливался и перезапускался немедленно.
• При использовании MIT-pthreads системный вызов s l e e p () не может быть пре-
рван с помощью сигнала SIGINT (прервать). Об этом стоит помнить, только если
вы запускаете mysqladmin — s l e e p . Вы должны ожидать завершения вызова
s l e e p (), прежде чем прерывание отработает и процесс остановится.
• Во время компоновки вы можете получить предупреждения, подобные показан-
ным ниже (как минимум, в среде Solaris), которые можно игнорировать:
Id: warning: symbol v _iob' has differing sizes:
(file /my/local/pthreads/lib/libpthread.a(findfp.o) value=0x4;
f i l e /usr/lib/libc.so value=0xl40);
/my/local/pthreads/lib/libpthread.a(findfp.o) definition taken
Id: warning: symbol ч iob 1 has differing s i z e s :
(file /my/local/pthreads/lib/libpthread.a(findfp.o) value=0x4;
f i l e /usr/lib/libc.so value=0xl40);
/my/local/pthreads/lib/libpthread.a(findfp.o) definition taken
• Ряд других предупреждений также можно проигнорировать:
4
i m p l i c i t d e c l a r a t i o n of function int s t r t o l l ( . . . ) '
4
i m p l i c i t d e c l a r a t i o n of function int strtoul(...)'
• Мы не смогли заставить r e a d l i n e работать с MIT-pthreads (Вообще говоря, на-
стоятельной необходимости в этом нет, но, возможно, кому-то будет интересно.)
2.3. Установка MySQL из исходного дистрибутива 133

2.3.6. Установка MySQL из исходных дистрибутивов


под Windows
В этом разделе описывается сборка бинарного дистрибутива MySQL версии 4.1 и
выше под Windows. Приводятся инструкции по сборке из стандартного исходного дист-
рибутива или из дерева репозитория BitKeeper, содержащего самые последние версии
исходных текстов.
; На заметку!
Г Инструкции, предложенные в настоящем разделе, предназначены строго для тех пользователей,
; которые хотят протестировать MySQL под Windows, собранный из исходного дистрибутива или
у же из дерева BitKeeper. Для производственного использования компания MySQL AB не советует
* применять сервер MySQL, самостоятельно собранный вами из исходных текстов. Обычно лучше
воспользоваться заранее скомпилированным бинарным дистрибутивом MySQL, собранным
7, MySQL AB специально для обеспечения оптимальной производительности в среде Windows. Ин-
;, струкции по установке бинарного дистрибутива можно найти в разделе 2.2.1.

Для сборки MySQL под Windows вам понадобятся следующий компилятор и ресур-
сы, доступные в системе Windows:
• Компилятор VC++ 6.0 (обновленный с использованием пакетов обновлений Ser-
vice Pack 4 и Service Pack 5, а также пакета препроцесора). Пакет препроцессора
необходим макроассемблеру. Дополнительную информацию можно найти по ад-
ресу:
http://msdn.microsoft.com/vstudio/downloads/updates/sp/vs6/sp5/faq.aspx.
• Около 45 Мбайт дискового пространства.
• 64 Мбайт оперативной памяти.
Вам также понадобится исходный дистрибутив MySQL для Windows. Существуют
два способа получить исходный дистрибутив MySQL 4.1 и выше:
1. Получить исходный дистрибутив, упакованный компанией MySQL AB для кон-
кретной версии MySQL, в которой вы заинтересованы. Предварительно упако-
ванные исходные дистрибутивы версий официальных релизов MySQL доступны
для загрузки по адресу http://dev.mysql.com/downloads.
2. Подготовить исходный дистрибутив самостоятельно из последнего дерева исход-
ных текстов, хранящихся в репозитории BitKeeper. Если вы планируете поступить
так, вам придется создать пакет в системе Unix, а затем перенести его в среду
Windows. (Причина состоит в том, что некоторые шаги конфигурирования и
сборки требуют использования инструментов, которые доступны только в Unix.)
Подход с BitKeeper требует наличия:
• системы на базе Unix или Linux;
• установленного в этой системе BitKeeper 3.0. Его можно получить по адресу
http://www.bitkeeper.com.
Если у вас имеется исходный дистрибутив для Windows, вы можете перейти непо-
средственно к разделу 2.3.6.1. Для сборки из дерева BitKeeper обратитесь к разделу
2.3.6.2.
Если вы обнаружите, что что-то не работает, как ожидалось, или у вас есть предло-
жения по усовершенствованию текущего процесса сборки под Windows, присылайте
свои предложения в список рассылки Win32 (см. раздел 1.7.1.1).
134 Глава 2. Установка MySQL

2.3.6.1. Сборка MySQL с использованием VC++


Щ На заметку!
Ц Файлы рабочих пространств VC++ для MySQL 4.1 и выше, тестируются персоналом MySQL AB
Щ перед выходом каждого выпуска, и совместимы с Microsoft Visual Studio 6.0 и выше (7.0/.NET).
Для сборки MySQL выполните следующие шаги:
1. Создайте рабочий каталог (например, С: \workdir).
2. Распакуйте исходный дистрибутив в упомянутый каталог с помощью WinZip или
другого инструмента Windows, который может читать zip-файлы.
3. Запустите компилятор VC++ 6.0.
4. В меню File (Файл) среды VC++ выберите пункт Open Workspace (Открыть ра-
бочее пространство).
5. Откройте файл рабочего пространства mysql.dsw, который находится в упомяну-
том выше каталоге.
6. В меню Build (Сборка) выберите пункт Set Active Configuration (Установить ак-
тивную конфигурацию).
7. Выберите в диалоговом окне mysqld - Win32 и щелкните на кнопке ОК.
8. Нажмите клавишу <F7> для запуска сборки отладочной версии сервера, библио-
тек и набора клиентских приложений.
9. Аналогичным образом скомпилируйте окончательную версию.
10. Отладочные версии программ и библиотек помещаются в каталоги client_debug
и lib_debug. Окончательные версии, соответственно, в c l i e n t _ r e l e a s e и
l i b r e l e a s e . Если вы хотите собрать и отладочные и окончательные версии, вы-
берите в меню Build пункт Build All (Собрать все).
11. Протестируйте сервер. Сервер, собранный по указанным выше инструкциям,
предполагает, что базовым каталогом MySQL и каталогом данных будут по умол-
чанию, соответственно, C:\mysql и C:\mysql\data. Если вы хотите тестировать
сервер, используя корневой каталог исходного дерева и его каталог данных, об
этом нужно будет сообщить серверу. Это можно сделать либо с помощью опций
командной строки —basedir и —datadir, либо поместить соответствующие оп-
ции в файл настроек (файл my.ini в каталоге Windows или файл С:\my.cnf). Если
вы хотите использовать каталог данных, расположенный где-либо еще, укажите
его путь.
12. Запустите сервер из каталога client_release или client_debug, в зависимости от
того, какой сервер необходимо использовать. Общие инструкции по запуску сер-
вера содержатся в разделе 2.2.1. Вам надо соответствующим образом адаптиро-
вать инструкцию, если применяется другой базовый каталог и каталог данных.
13. Когда сервер запущен на основе указанной вами конфигурации в виде автономно-
го приложения или службы, попытайтесь подключиться к нему из интерактивной
утилиты командной строки mysql, которая расположена в вашем каталоге
client_release или client__debug.
Как только вы убедитесь, что собранные вами программы функционируют коррект-
но, остановите сервер. Затем установите MySQL, как описано ниже.
2.3. Установка MySQL из исходного дистрибутива 135

1. Создайте систему каталогов, куда MySQL должен быть установлен. Например,


для установки в каталог С: \mysql потребуется выполнить следующие команды:
С:\> mkdir C:\mysql
С:\> mkdir C:\mysql\bin
С:\> mkdir C:\mysql\data
С:\> mkdir С:\mysql\share
С:\> mkdir C:\mysql\scripts
Если вы хотите скомпилировать другие клиентские программы и присоединить их
к MySQL, нужно будет создать еще несколько дополнительных каталогов:
С:\> mkdir C:\mysql\include
С:\> mkdir C:\mysql\lib
С:\> mkdir C:\mysql\lib\debug
С:\> mkdir C:\mysql\lib\opt
Если вы хотите проводить тестирование производительности MySQL, создайте
еще один каталог:
С:\> mkdir C:\mysql\sql-bench
Тестирование производительности требует поддержки языка Perl.
2. Из каталога workdir скопируйте в С: \mysql содержимое следующих подкаталогов:
С:\> cd \workdir
C:\workdir> copy client_release\*.exe C:\mysql\bin
С:\workdir> copy client_debug\mysqld.exe С:\mysql\bin\mysqld-debug.exe
C:\workdir> xcopy scripts\*.* C:\mysql\scripts /E
C:\workdir> xcopy share\*.* C:\mysql\share /E
Если вы хотите компилировать другие клиентские программы и подключать их к
MySQL, нужно будет также скопировать некоторые библиотеки и файлы заголовков:
C:\workdir> copy lib_debug\mysqlclient.lib C:\mysql\lib\debug
C:\workdir> copy lib_debug\libmysql.* C:\mysql\lib\debug
C:\workdir> copy lib_debug\zlib.* C:\mysql\lib\debug
C:\workdir> copy lib_release\mysqlclient.lib C:\mysql\lib\opt
C:\workdir> copy lib_release\libmysql.* C:\mysql\lib\opt
C:\workdir> copy lib_release\zlib.* C:\mysql\lib\opt
C:\workdir> copy include\*.h C:\mysql\include
C:\workdir> copy libmysql\libmysql.def C:\mysql\include
Если планируется проводить тестирование производительности MySQL, необхо-
димо выполнить следующую команду:
C:\workdir> xcopy sql-bench\*.* C:\mysql\bench /Е
Установите и запустите сервер точно так же, как вы это делали для бинарного дист-
рибутива (см. раздел 2.2.1).

2.3.6.2. Создание исходного пакета для Windows из текстов,


находящихся в разработке
Чтобы создать исходный пакет для Windows из дерева, хранящегося в репозитории
BitKeeper, воспользуйтесь следующими инструкциями. Обратите внимание, что эта про-
цедура может быть выполнена на машинах под управлением Unix или Unix-подобной
операционной системы. Так, например, известно, что она хорошо работает в среде Linux.
136 Глава 2. Установка MySQL

1. Загрузите исходное дерево MySQL (версии 4.1 или выше) из репозитория


BitKeeper. Более подробная информация о том, как загружать исходное дерево,
находится в разделе 2.3.3.
2. Сконфигурируйте и соберите дистрибутив. Сделать это можно с помощью сле-
дующей команды в корневом каталоге исходного дерева:
shell> ./BUILD/coinpile-pentium-max
3. После того, как убедитесь, что процесс сборки завершился успешно, запустите
следующий сценарий из корневого каталога исходного дерева:
shell> ./scripts/make_win_src_distribution
Этот сценарий создает исходный пакет для Windows. Сценарию можно указать
различные опции, в соответствии с вашими потребностями:
• —help. Отобразить справочную информацию.
• —debug. Выводить информацию о выполняемых операциях, не создавая пакета.
• — dirname. Имя каталога для копирования файлов (промежуточного).
• —silent. He выводить список обрабатываемых файлов.
• --suffix. Суффикс имени пакета.
• —tar. Создавать пакет . t a r . gz вместо .zip.
• —trap. Расположение временных файлов.
По умолчанию сценарий make_win_src_distribution создает архив в формате Zip
с именем mysql-BEPCH#-win-src.zip, где ВЕРСИЯ представляет номер версии
MySQL исходного дерева.
4. Скопируйте или загрузите полученный исходный пакет на Windows-машину.
Чтобы затем скомпилировать его, ознакомьтесь с инструкциями в разделе 2.3.6.1.

2.3.7. Компиляция клиентских программ MySQL под Windows


В исходных файлах необходимо включить файл my_global.h перед mysql .h:
#include <my_global.h>
#include <mysql.h>
myglobal.h включает все другие заголовочные файлы, необходимые для достиже-
ния совместимости с Windows (такие как windows.h), если вы компилируете программы
для Windows.
Скомпоновать свой код можно либо с динамической библиотекой libmysql.lib, ко-
торая служит оболочкой для загрузки libmysql .dll по требованию, либо со статической
библиотекой mysqlclient. lib.
Клиентские библиотеки MySQL компилируются с поддержкой потоков, поэтому вы
должны также компилировать код, как многопоточный.

2.4. Настройки и тестирование после установки


После установки MySQL остается еще ряд вещей, которые потребуется сделать. На-
пример, в среде Unix вы должны инициализировать каталог данных и создать таблицы
привилегий. На всех платформах важным обстоятельством, имеющим отношение к
безопасности, является то, что начальные пользовательские учетные записи в MySQL не
2.4. Настройки и тестирование после установки 137

имеют паролей. Вы должны незамедлительно присвоить им пароли, дабы предотвратить


неавторизованный доступ к серверу MySQL.
В следующих разделах описаны постустановочные процедуры, которые специфичны
для систем на базе Windows и Unix. Следующий раздел 2.4.4 касается всех платформ. Он
объясняет, что делать, если доводится сталкиваться с проблемами во время запуска сер-
вера. Раздел 2.4.5 также относится ко всем платформам. Вы должны выполнить инст-
рукции этого раздела, чтобы гарантировать правильную защиту пользовательских учет-
ных записей MySQL за счет установки для них паролей.
Когда вы будете готовы к регистрации новых пользователей, можете ознакомиться с
информацией о системе контроля доступа MySQL и управлении учетными записями (см.
разделы 4.4 и 4.5).

2.4.1. Постустановочные процедуры под Windows


В среде Windows каталог данных и таблицы привилегий создавать не нужно. Дист-
рибутив MySQL для Windows включает в себя таблицы привилегий с заранее установ-
ленными начальными пользовательскими учетными записями в базе данных mysql, на-
ходящейся в каталоге данных. Однако им потребуется назначить пароли. То, как это де-
лается, описано в разделе 2.4.5.
До установки паролей вы можете попробовать запустить некоторые клиентские про-
граммы, дабы убедиться, что вы можете подключаться к серверу и что он работает пра-
вильно. Убедившись в том, что сервер работает (см. раздел 2.2.1.5), выполните приве-
денные ниже команды, чтобы проверить, можете ли вы получать информацию от серве-
ра. Вывод должен выглядеть примерно так, как показано ниже:
С:\> C:\mysql\bin\mysqlshow

I Databases |
+ +
I mysql |
I test I
+ +
С:\> C:\mysql\bin\mysqlshow mysql
Database: mysql

I Tables |
+
+
I columns_priv
I db
I func
host
tables_priv
user |
+ +
C:\> C:\mysql\bin\mysql -e "SELECT Host,Db,User FROM db" mysql

| host | db | user |

I % | test% | |
138 Глава 2. Установка MySQL

Если вы имеете дело с версией Windows, которая поддерживает службы, и хотите,


чтобы MySQL запускался автоматически при старте Windows, обратитесь в раздел
2.2.1.7 за более детальной информацией.

2.4.2. Постустановочные процедуры под Unix


После установки MySQL на Unix вам необходимо инициализировать таблицы приви-
легий, запустить сервер и убедиться в корректном его функционировании. Возможно,
будет произведена настройка сервера таким образом, чтобы он стартовал и останавли-
вался автоматически при запуске и останове системы. Вы также должны присвоить па-
роли учетным записям, содержащимся в таблицах привилегий.
Таблицы привилегий в Unix устанавливаются программой mysql_install_db. При
некоторых методах установки эта программа запускается автоматически:
• Если вы устанавливаете MySQL под Linux, используя дистрибутив в форме паке-
та RPM, то сервер RPM запускает mysql_install_db.
• Если вы устанавливаете MySQL под Mac OS X, используя дистрибутив PKG, ус-
тановщик также запускает mysql_install_db.
Во всех остальных случаях m y s q l i n s t a l l d b должен запускаться вручную.
Следующая процедура описывает инициализацию таблицы привилегий (если это еще
не было сделано) и последующий запуск сервера. Она также предлагает некоторые ко-
манды, которые можно использовать для тестирования сервера, чтобы убедиться в его
правильной работе. Информацию об автоматическом запуске и останове сервера можно
найти в разделе 2.4.3.
После того, как вы завершите процедуру и получите функционирующий сервер, вы
должны присвоить пароли учетным записям, созданным mysql_install_db. О том, как
это сделать, рассказывается в разделе 2.4.5.
В приведенных здесь примерах сервер запускается под идентификатором пользова-
тельской учетной записи mysql. Предполагается, что упомянутая учетная запись сущест-
вует. Либо создайте ее, если ее еще нет, либо подставьте имя другой учетной записи, с
использованием которой вы собираетесь запускать сервер.
1. Измените текущий каталог на корневой каталог вашей установки MySQL, пред-
ставленный здесь как БА30ВЫЙ_КАТАЛ0Г:
shell> cd БА30ВЫЙ_КАТАЛ0Г
По всей видимости, БА30ВЫЙ_КАТАЛ0Г будет чем-то вроде /usr/local/mysql или
/usr/local. При выполнении следующих шагов предполагается, что вы находи-
тесь в этом каталоге.
2. Если необходимо, запустите сценарий mysql_install_db, чтобы установить на-
чальное содержимое таблиц привилегий, в которых находится информация о том,
какие привилегии каким пользователям предоставляются для подключения к сер-
веру. Это необходимо делать, если применяется дистрибутив, который не выпол-
няет данное действие автоматически.
Обычно mysql_install_db должен запускаться только один раз - при первой уста-
новке MySQL, поэтому можете пропустить этот шаг, если выполняется модерниза-
ция существующей установки. mysql_install_db не перезаписывает существующие
таблицы привилегий, поэтому запускать его не опасно в любом случае. Чтобы
инициализировать таблицы привилегий, воспользуйтесь одной из двух команд,
2.4. Настройки и тестирование после установки 139

приведенных ниже, в зависимости от того, где находится mysqlinstalldb - в


подкаталоге bin или scripts:
shell> bin/mysql_install_db —user=mysql
shell > scripts /my sql_install_db —user=mysql
Сценарий mysql_install_db создает каталог данных, базу данных mysql, которая
содержит информацию обо всех привилегиях, и базу данных test, которую мож-
но использовать для тестирования MySQL. Этот сценарий также создает записи в
таблице привилегий для учетной записи root и анонимных учетных записей. Эти
учетные записи изначально не имеют паролей. Описание их начальных привиле-
гий можно найти в разделе 2.4.5. Привилегии позволяют учетной записи MySQL с
именем root делать все что угодно, а остальным - создавать или использовать ба-
зу данных под названием t e s t или начинающуюся на t e s t .
Важно убедиться, что каталоги баз данных и файлы принадлежат пользователь-
ской учетной записи операционной системы mysql, чтобы сервер имел доступ по
чтению и записи в эти каталоги позже, когда он будет запущен. Чтобы гарантиро-
вать это, при запуске сценария mysql_install_db должна указываться опция
—user, если вы запускаете его от имени root. В противном случае он должен за-
пускаться после входа в систему с использованием учетной записи mysql; тогда
опцию —user можно опустить.
mysql__install_db создает в базе данных mysql несколько таблиц: user, db, host,
tables_priv, columns_priv, func и, возможно, ряд других, в зависимости от вер-
сии MySQL.
Если вам не нужна база данных test, можете ее удалить с помощью команды
mysqladmin -u root drop t e s t после старта сервера.
В случае возникновения проблем с m y s q l i n s t a l l d b обратитесь в раздел 2.4.2.1
за пояснениями.
Существуют некоторые альтернативы запуску сценария m y s q l i n s t a l l d b , как
это предлагает дистрибутив MySQL:
• Если вам нужны начальные привилегии, отличающиеся от устанавливаемых
по умолчанию, можете модифицировать mysql_install_db перед его запус-
ком. Однако гораздо предпочтительнее использовать операторы GRANT и
REVOKE уже после того, как таблицы привилегий настроены. Другими словами,
вы можете запустить m y s q l i n s t a l l d b , а потом с помощью mysql -u root
mysql подключиться к серверу MySQL от имени учетной записи root и пре-
доставить или отозвать требуемые привилегии.
Если необходимо установить MySQL на множество машин с одними и теми
же привилегиями, можете поместить операторы GRANT и REVOKE в файл, и по-
том выполнять его как сценарий с помощью mysql после запуска
mysql_install_db. Например:
shell> bin/mysql_install_db —user=mysql
shell> bin/mysql -u root < ваш_файл_сценария
Поступая подобным образом, вы избегаете необходимости вводить показан-
ные операторы вручную на каждой машине.
140 Глава 2. Установка MySQL

• Существует возможность заново создать таблицы привилегий после того, как


они были созданы. Это может понадобиться, если во время изучения операто-
ров GRANT и REVOKE было внесено настолько много изменений после выполне-
ния mysql_install_db, что проще все очистить и создать заново.
Чтобы пересоздать таблицы привилегий, удалите все файлы . frm, .MYI и .MYD
из каталога, содержащего базу данных mysql (это каталог с именем mysql, ко-
торый расположен внутри каталога данных, выводимого в качестве значения
datadir при выполнении команды mysqld --help). После этого запустите сце-
нарий mysql_install_db заново.
| На заметку!
Jf? Для версий MySQL, предшествующих 3.22.10, вы не должны удалять файлы . f r m . Если вы не-
ff преднамеренно сделаете это, скопируйте их обратно в каталог mysql из дистрибутива MySQL до
|| запуска m y s q l _ i n s t a l l _ d b .
• mysqld можно запустить вручную с опцией —skip-grant-tables и добавить
нужные привилегии с использованием mysql:
shell> bin/mysqld_safe —user=mysql —skip-grant-tables &
shell> bin/mysql mysql
Из среды mysql выдайте команды SQL, содержащиеся в сценарии
mysql_install_db. He забудьте затем запустить mysqladmin flush-privileges или
mysqladmin reload, чтобы заставить сервер перечитать таблицы привилегий.
Помните, что если вы не пользуетесь сценарием mysql_install_db, то не толь-
ко должны будете заполнить таблицы привилегий вручную, но еще и предва-
рительно создать их.
3. Запустите сервер MySQL:
shell> bin/mysqldjsafe —user=mysql &
Для версий MySQL, предшествующих 4.0, замените bin/mysqld_safe на
bin/safe_mysqld.
Важно, чтобы сервер MySQL запускался от имени учетной записи непривилеги-
рованного пользователя (не root). Для этого при запуске mysql_safe от имени
root необходимо указать опцию —user. Если же сценарий запускается от имени
пользователя mysql, опцию —user можно опустить. Дополнительную информа-
цию о запуске MySQL от имени непривилегированного пользователя можно най-
ти в разделе А.3.2.
Если вы пренебрегаете созданием таблиц привилегий до выполнения этого ша-
га, то при попытке запуска сервера в журнале ошибок появится следующее со-
общение:
mysqld: Can't find f i l e : 'host.frm 1
mysqld: Невозможно найти файл: 'host.frm1
Если вы столкнетесь с какими-то другими проблемами во время запуска сервера,
просмотрите раздел 2.4.4.
4. Воспользуйтесь mysqladmin для проверки функционирования сервера. Приведен-
ные ниже команды обеспечивают проверку, запущен ли сервер и отвечает ли он
на запросы соединений:
2.4. Настройки и тестирование после установки 141

shell> bin/mysqladmin version


shell> bin/mysqladmin variables
Вывод команды mysqladmin version слегка отличается от платформы к платфор-
ме и от версии к версии MySQL, но должен быть подобен показанному ниже:
shell> bin/mysqladmin version
mysqladmin Ver 8.40 Distrib 4.0.18, for linux on i586
Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL license
Server version 4.0.18-log
Protocol version 10
Connection Localhost via Unix socket
TCP port 3306
UNIX socket /tmp/mysql.sock
Uptime: 16 sec
Threads: 1 Questions: 9 Slow q u e r i e s : 0
Opens: 7 Flush t a b l e s : 2 Open t a b l e s : 0
Queries per second avg: 0.000
Memory in u s e : 132K Max memory used: 16773K
Чтобы посмотреть, что еще можно делать с помощью mysqladmin, запустите его с
ключом --help.
5. Проверьте, можете ли вы остановить сервер:
shell> bin/mysqladmin -u root shutdown
6. Проверьте, можете ли вы перезапустить сервер. Делайте это с использованием
mysqld_saf e или вызывая mysqld непосредственно, например:
shell> bin/mysqld_safe —user=mysql —log &
Если mysqld_saf e не работает, обратитесь в раздел 2.4.4.
7. Выполните некоторые простые тесты, чтобы убедиться в возможности получения
информации от сервера. Вывод должен быть похож на приведенный ниже:
С: \> С: \mysql\bin\mysqlshow
+ +
| Databases |
+ +
I mysql |
I test !
+ +
С:\> C:\mysql\bin\mysqlshow mysql
Database: mysql
I Tables |
+ +
| columns_priv |
I db |
I func I
I host |
I tablesjpriv |
I user |
142 Глава 2. Установка MySQL

С:\> C:\mysql\bin\mysql -е "SELECT Host,Db,User FROM db" mysql


+ + + +
I host | db | user |
+ + + +
I % I test | |
I % | testJ| |
+ + + +
8. В подкаталоге sql-bench находится комплект тестов производительности, с по-
мощью которого можно сравнить, как работает MySQL на различных платфор-
мах. Эти тесты написаны на языке Perl с использованием модуля DBI, обеспечи-
вающего независимый от базы данных интерфейс к различным базам. Для запуска
этого комплекта тестов необходимы и другие дополнительные модули Perl. Пона-
добится установить следующие модули:
DBI
DBD::mysql
Data::Dumper
Data::ShowTable
Все эти модули можно получить на сайте CPAN (http://www.cpan.org). См. раз-
дел 2.7.1.
Каталог sql -bench/Results содержит результаты запуска многих тестов на раз-
личных базах данных и платформах. Чтобы запустить все тесты, выполните ко-
манды:
shell> cd sql-bench
shell> perl run-all-tests
Если у вас нет каталога sql-bench, это означает, что возможно, MySQL был уста-
новлен с использованием других файлов RPM, а не тех, что содержат исходный
дистрибутив (исходный RPM включает каталог sql-bench). В этом случае потре-
буется установить комплект тестов производительности. Начиная с MySQL 3.22,
поставляется отдельный RPM-файл тестов под названием mysqlbench-ВЯРСИЯ-
i386. rpm, который содержит код и данные.
В исходном дистрибутиве также имеется каталог t e s t с другими тестами, кото-
рые можно запускать. Например, чтобы запустить тест autoincrement.tst, вы-
полните следующую команду из корневого каталога исходного дистрибутива:
shell> mysql -wf test < ./tests/auto_increment.tst
С ожидаемыми результатами этого теста можно ознакомиться в файле
./tests/auto_increment.res.
9. К этому моменту вы должны иметь работающий сервер. Однако ни одна их на-
чальных учетных записей MySQL пока не имеет пароля, поэтому придется при-
своить им пароли, пользуясь инструкциями из раздела 2.4.5.

2.4.2.1. Проблемы с выполнением mysqMnstalldb


Назначение сценария mysql_install_db состоит в том, чтобы генерировать таблицы
привилегий MySQL. Он не перезаписывает существующих таблиц привилегий и не за-
трагивает никакие другие данные.
2.4. Настройки и тестирование после установки 143

Если вы хотите пересоздать существующие таблицы привилегий, сначала остановите


сервер mysqld. Переименуйте подкаталог mysql каталога данных, чтобы тем самым со-
хранить его, и затем запустите сценарий mysql_install_db:
shell> mv каталог-данных-mysql/mysql каталог-данных-mysql/mysql-old
shell> mysql_install_db —user=mysql
В настоящем разделе перечислены проблемы, с которыми можно столкнуться при
запуске mysql_install_db.
• mysql_install_db не устанавливает таблицы привилегий.
Вы можете обнаружить, что сценарий не установил таблицы привилегий и пре-
рвал выполнение с выдачей следующих сообщений:
Starting mysqld daemon with databases from XXXXXX
mysqld ended
Запуск демона mysqld для баз данных из XXXXXX
mysqld завершен
В этом случае потребуется тщательно исследовать файл журнала ошибок. Журнал
должен находится в каталоге XXXXXX, иметь имя, соответствующее сообщению об
ошибке, и указывать на причину, по которой mysqld не смог запуститься. Если вы
не можете понять, что случилось, включите этот журнал в сообщение об ошибке и
отправьте его в MySQL AB (см. раздел 1.7.1.3).
• Процесс mysqld уже выполняется.
Это означает, что сервер уже запущен и в этом случае вполне вероятно, что таб-
лицы привилегий уже созданы. Если это так, вам вообще не нужно запускать
mysql_install_db, поскольку он должен запускаться только один раз (при первой
установке MySQL).
• Установка второго сервера mysqld не работает, когда функционирует первый сервер.
Это может произойти, когда у вас уже есть существующая установка MySQL, но
вы хотите выполнить новую установку в другой каталог. Например, в дополнение
к рабочей копии требуется создать еще одну копию для целей тестирования. Во-
обще говоря, проблема, которая возникает при попытке запуска второго сервера,
заключается в том, что он пытается использовать сетевой интерфейс, который уже
занят первым сервером. В этом случае вы увидите одной из следующих сообще-
ний об ошибках:
Can't s t a r t server: Bind on TCP/IP port:
Address already in use
Can't s t a r t server: Bind on unix s o c k e t . . . .
Невозможно запустить сервер: Привязка к порту TCP/IP:
Адрес уже используется
Невозможно запустить сервер: Привязка к сокету unix....
Инструкции по настройке нескольких серверов представлены в разделе 4.9.
• Вы не имеете доступа по записи в каталог /tmp.
Если у вас нет доступа по записи, чтобы создавать временные файлы или файлы
сокетов Unix в каталоге по умолчанию (/tmp), эта ошибка возникает при запуске
mysql_install_db или сервера mysqld.
144 Глава 2. Установка MySQL

Можно указать другой каталог для временных файлов и файла сокета, выполнив
приведенные ниже команды до запуска mysql_install_db или mysqld:
shell> TMPDIR=/временный_каталог/
she 11 > MYSQLJJNIX_PORT=/some_tmpjiir/mysql. sock
shell> export TMPDIR MYSQLJJNIX_PORT
В качестве параметра временный_каталог должен быть указан полный путь к ка-
талогу, для которого имеется доступ по записи.
После этого у вас появится возможность выполнить mysql_install_db и запус-
тить сервер:
shell> bin/mysql_install_db —user=mysql
shell> bin/mysqld_safe —user=mysql &
Если mysql_install_db находится в каталоге scripts, поменяйте в первой коман-
де bin на scripts.
За дополнительной информацией обращайтесь в раздел А.4.5 и в приложение Б.

2.4.3. Автоматический запуск и останов MySQL


Обычно сервер mysql запускается одним из следующих способов:
• Прямым обращением к mysqld. Это работает на любой платформе.
• Запуском сервера MySQL в виде службы Windows. Это можно сделать в
Windows-системах, которые поддерживают системные службы (NT, 2000 и ХР).
Служба может быть настроена на автоматический запуск при старте Windows ли-
бо на ручной запуск по запросу. Подробные инструкции приведены в разделе
2.2.1.7.
• Вызовом сценария mysqld_saf е, который пытается определить подходящие опции
для mysqld и затем запускает его с этими опциями. Этот сценарий используется в
системах, базирующихся на BSD Unix. См. раздел 4.1.3.
• Вызовом mysql. server. Этот сценарий применяется преимущественно при запус-
ке и останове операционных систем, использующих каталог запуска в стиле
System-V, где он обычно устанавливается под именем mysql. Сценарий
mysql.server запускает сервер, вызывая, в свою очередь, mysqld_safe. См. раздел
4.1.4.
• В системе Mac OS X можно установить отдельный пакет приложения MySQL
Startup Item, чтобы обеспечить автоматический запуск MySQL при загрузке сис-
темы. Startup Item запускает сервер, вызывая mysql. server. См. раздел 2.2.3.
Сценарии mysqld.server и mysqld_safe, а также Mac OS X Startup Item, могут ис-
пользоваться для запуска сервера вручную или автоматического запуска во время старта
системы. Кроме того, mysqld. server и Startup Item могут применяться для останова сер-
вера.
Чтобы запустить или остановить сервер вручную с помощью сценария mysql.server,
вызывайте его, соответственно, с аргументами s t a r t и stop:
shell> mysql.server start
shell> mysql.server stop
2.4. Настройки и тестирование после установки 145

Прежде чем запустить сервер, mysql. server изменяет текущий каталог на каталог ус-
тановки MySQL, после чего вызывает mysqld_saf е. Если требуется запускать сервер от
имени какого-то специфического пользователя, добавьте соответствующую позицию
user в раздел [mysqld] файла опций /etc/my, cnf, как показано ниже в настоящем разде-
ле. (Возможно, вам придется отредактировать сценарий mysql.server, если бинарный
дистрибутив MySQL был установлен в нестандартное место. Модифицируйте упомяну-
тый сценарий так, чтобы перед запуском mysqldsafe по команде cd выполнялся пере-
ход в нужный каталог. Если это было сделано, то при будущих обновлениях измененная
версия mysql.server может быть перезаписана, поэтому отредактированный вариант
сценария необходимо скопировать в безопасное место.)
mysql.server останавливает сервер, посылая ему сигнал. Сервер можно остановить
также b вручную, выполнив команду mysqladmin shutdown.
Чтобы MySQL запускался и останавливался автоматически на вашем сервере, необ-
ходимо добавить команды запуска и останова в соответствующие места в файлах
/etc/rc*.
Если используется RPM-пакет сервера для Linux (MySQL-server-ВЕРСЯЯ.грт), сцена-
рий mysql.server автоматически устанавливается в каталог /etc/init.d под именем
mysql. Нет необходимости устанавливать его вручную. Более подробная информация о
пакетах RPM для Linux представлена в разделе 2.2.2.
Некоторые поставщики предлагают RPM-пакеты, которые устанавливают сценарий
запуска под другим именем, например, mysqld.
Если вы устанавливаете MySQL из исходного дистрибутива либо используете бинар-
ный дистрибутив в формате, который не выполняет автоматическую установку
mysql.server, можете сделать это вручную. Сценарий расположен в подкаталоге
support-files каталога установки MySQL или в дереве исходных текстов.
Чтобы установить mysql.server вручную, скопируйте его в каталог / e t c / i n i t . d под
именем mysql и сделайте его исполняемым:
shell> cp mysql.server /etc/init.d/mysql
shell> chmod +x /etc/init.d/mysql
Более старые системы Red Hat используют каталог /etc/rc.d/init.d вместо
/etc/init.d. В этих системах соответствующим образом уточните предыдущие коман-
ды. В качестве альтернативного решения, сначала создайте /etc/init.d как символиче-
скую ссылку, которая будет указывать на /etc/rc.d/init.d:
shell> cd /etc
shell> In -s re.d/init.d .
После установки сценария команды его активизации зависят от используемой опера-
ционной системы. В Linux для этого применяется команда chkconf ig:
shell> chkconfig —add mysql
В некоторых Linux-системах для полной активизации сценария потребуется выдать
следующую команду:
shell> chkconfig —level 345 mysql on
В системе FreeBSD сценарии запуска обычно должны устанавливаться в
/usr/local/etc/rc.d/. Страницы man-руководства гс(8) указывают, что сценарии из
этого каталога выполняются, только если их имена соответствуют шаблону *.sh. Все
146 Глава 2. Установка MySQL

остальные файлы и подкаталоги, находящиеся внутри этого каталога, молча игнориру-


ются. Другими словами, в системе FreeBDS потребуется установить mysql. server как
/usr/local/etc/rc.d/mysql. server. sh, чтобы обеспечить его автоматический запуск.
В качестве альтернативы способу, описанному выше, некоторые операционные сис-
темы также используют /etc/rc.local или /etc/init.d/boot.local для запуска допол-
нительных служб во время загрузки. Чтобы запустить MySQL таким способом, добавьте
в соответствующий файл запуска команду, подобную следующей:
/bin/sh -с 'cd /usr/local/mysql; ./bin/mysqld_safe —user=mysql &'
Для ознакомления с установкой сценария запуска в средах других операционных
систем читайте документацию по системе.
Опции для mysql.server можно добавить в глобальный файл /etc/my.cnf. Ниже по-
казано типичное содержимое файла /etc/my. cnf:
[mysqld]
datadir=/usr/local/mysql/var
socket=/var/tmp/mysql.sock
port=3306
user=mysql
[mysql.server]
basedir=/usr/local/mysql
Сценарий mysql. server понимает следующие опции: basedir, datadir и pid-f i l e .
Если они должны быть указаны, их следует поместить в файл опций, а не в команд-
ную строку. В качестве аргументов командной строки mysql.server воспринимает толь-
ко start и stop.
Ниже перечислены группы опций, которые сервер и сценарий запуска читают из
файла опций.
Сценарий Группы опций
mysqld [mysqld], [server], [mysqld-старшая-версия]
mysql.server [mysqld], [mysql.server]
mysqld_safe [mysqld], [server], [mysqld_safe]
[mysqld-старшая-версия) означает, что группы с именами вроде [mysqld-4.0],
[mysqld-4.1] и [mysqld-5.0] будут прочитаны серверами MySQL 4.0.x, 4.1.x, 5.0.x и так
далее. Эта возможность появилась в MySQL 4.0.14. Она может использоваться для ука-
зания опций, которые будут прочитаны только серверами конкретных версий.
Для достижения обратной совместимости mysql.server также читает группу
[mysql_server], a mysqld_safe - группу [safejnysqld]. Однако все же потребуется об-
новить файлы опций, чтобы они вместо этого использовали группы [mysql.server] и
[mysqld_safe], если работа выполняется с MySQL 4.0 или более поздней версией.
См. раздел 3.3.2.

2.44. Запуск сервера MySQL и устранение


неисправностей
Если при запуске сервера возникли какие-то проблемы, попробуйте сделать следую-
щие вещи:
2.4. Настройки и тестирование после установки 147

• Укажите специальные опции, необходимые используемому вами механизму хра-


нения.
• Убедитесь в том, что серверу известно местонахождение каталога данных.
• Убедитесь в том, что сервер может работать с каталогом данных. Атрибуты вла-
дения и доступа, присвоенные каталогу данных и его содержимому, должны быть
такими, чтобы обеспечивать серверу доступ к ним и возможность модификации.
• Просмотрите журнал ошибок, чтобы разобраться, почему сервер не может стартовать.
• Проверьте доступность сетевого интерфейса, который использует сервер.
Некоторые механизмы хранения имеют опции, управляющие их поведением. Можно
создать файл my.cnf и указать в нем опции для используемого механизма. Если вы будете
использовать механизмы хранения, которые поддерживают транзакционные таблицы
(innoDB, BDB), то перед запуском сервера убедитесь, что они должным образом настроены:
• Если вы используете таблицы InnoDB, обратитесь к специфичным для InnoDB оп-
циям запуска. В MySQL 3.23 InnoDB нужно конфигурировать явно, в противном
случае сервер при запуске выдаст сбой. Начиная с MySQL 4.0, InnoDB использует
значения по умолчанию для конфигурационных опций, которые не указаны явно.
См. раздел 9.4.
• Если вы используете таблицы BDB (Berkley DB), необходимо ознакомиться с раз-
личными специфическими для BDB опциями запуска. См. раздел 8.4.3.
После запуска mysqld делает текущим каталог данных. Это место, где он ожидает
найти базы данных и куда собирается писать файлы журналов. В среде Unix сервер
mysqld также пишет в каталог данных файл pid (файл идентификатора процесса).
Местоположение каталога данных по умолчанию прописывается в код сервера во
время его компиляции. Если каталог данных находится где-то в другом месте системы,
сервер не сможет правильно работать. Узнать значения путей по умолчанию можно, вы-
звав mysqld с опциями —verbose и —help (до версии 4.1 MySQL игнорировал опцию
—verbose).
Если пути по умолчанию не соответствуют раскладке установки MySQL в вашей
системе, можете переопределить их с помощью опций командной строки для mysqld или
mysqld_saf е. Их также можно задать в файле опций.
Для явного указания местоположения каталога данных служит опция —datadir. Од-
нако обычно можно указать mysqld местоположение базового каталога, в котором уста-
новлен MySQL, и он найдет каталог данных там. Это можно сделать с помощью опции
—basedir.
Чтобы проверить действие указания опций путей, вызовите mysqld с этими опциями
и дополните их список —verbose и —help. Например, если вы измените местоположе-
ние на каталог, в котором установлен mysqld, а затем выполните приведенную ниже ко-
манду, она покажет, что сервер стартовал с базовым каталогом /usr/local:
shell> ./mysqld —basedir=/usr/local —verbose —help
Можно также задать и другие опции, подобные --datadir, но помните, что
—verbose и —help должны быть последними. (Для версий MySQL, предшествующих
4.1, —verbose необходимо опустить.)
Как только вы определите, что сервер соответствующим образом воспринял установ-
ки путей, запускайте его без опций —verbose и —help.
148 Глава 2. Установка MySQL

Если mysqld уже работает, узнать текущие установки путей можно с помощью сле-
дующей команды:
shell> mysqladmin variables
или
shell> mysqladmin -h имя_хоста variables
Здесь имя_хоста - это имя хоста, на котором работает сервер MySQL.
Если при запуске mysqld выдается ошибка Err code 13 ("Permission denied" - "Нару-
шение прав доступа"), это означает, что установленные привилегии для каталога данных
или его содержимого не позволяют серверу получить к нему доступ. В этом случае из-
мените права доступа к каталогу и файлам, чтобы сервер смог работать с ними. Вы так-
же можете запустить сервер от имени root, но это подвергает систему риску нарушения
безопасности, поэтому такого способа следует избегать.
В среде Unix перейдите в каталог данных и проверьте права владения для этого ката-
лога и его содержимого, дабы убедиться, что сервер имеет к нему доступ. Например,
если каталогом данных является /usr/local/mysql/var, введите команду:
shell> Is -la /usr/local/mysql/var
Если каталог данных, его файлы или подкаталоги не принадлежат пользователю опе-
рационной системы, от имени которого запущен сервер, измените их права владения:
shell> chown -R mysql /usr/local/mysql/var
shell> chgrp -R mysql /usr/local/mysql/var
Если сервер не может стартовать корректно, проверьте файл журнала ошибок на
предмет наличия в нем объяснения причины. Файлы журналов размещаются в каталоге
данных (обычно C:\mysql\data под Windows, /usr/local/mysql/data - для бинарных
дистрибутивов Unix и /usr/local/var - для исходных дистрибутивов Unix). Ищите в
этом каталоге файлы с именами имя_хоста. e r r и имя^хоста. log, где имя_хоста - это имя
хоста вашего сервера. (Старые серверы под Windows в качестве имени файла журнала
ошибок использовали mysql.err.) Затем просмотрите несколько последних строк этих
файлов. В Unix для вывода нескольких последних строк можно воспользоваться коман-
дой t a i l :
shell> t a i l имя_хоста.етг
shell> t a i l имя_хоста.log
Журнал ошибок содержит информацию о том, почему сервер не смог запуститься.
Например, вы можете увидеть там нечто вроде:
000729 14:50:10 bdb: Recovery function for LSN 1 27595 failed
000729 14:50:10 bdb: warning: . / t e s t / t l . d b : No such f i l e or directory
000729 14:50:10 Can't i n i t databases
Это означает, что вы не запустили mysqld с опцией — bdb-no-recover, а механизм
хранения Berkley DB обнаружил, что у него что-то не так с собственными журнальными
файлами, когда попытался восстановить базу данных. Чтобы продолжить работу, вам
нужно переместить старые журнальные файлы Berkley DB из каталога данных в какое-
нибудь другое место, где их можно будет позже просмотреть. Журнальные файлы BDB
называются последовательно, начиная с log.0000000001, где номер увеличивается каж-
дый раз.
2.4. Настройки и тестирование после установки 149

Если вы запускаете mysqld с поддержкой таблиц BDB, и он выдает сбой во время стар-
та, это может быть вызвано проблемами с журналом восстановления BDB. В этом случае
можно попробовать запустить его с опцией —bdb-no-recover. Если это поможет, удали-
те все журнальные файлы BDB из каталога данных и попробуйте снова запустить mysqld
без опции —bdb-no-recover.
Если возникает одна из следующих ошибок, это означает, что какая-то другая про-
грамма (возможно, другой сервер mysqld) уже использует порт TCP/IP или Unix-сокет,
которые пытается открыть mysqld:
Can't s t a r t server: Bind on TCP/IP port: Address already in use
Can't s t a r t server: Bind on unix socket...
С помощью команды ps проверьте, не запущен ли на машине другой сервер mysqld.
Если да, остановите его. (Если другой сервер выполняется, и вы действительно хотите,
чтобы на машине функционировало несколько серверов, ознакомьтесь с информацией,
представленной в разделе 4.9.)
Если никакой другой сервер не запущен, попробуйте выполнить команду telnet
имя-вашего-хоста номер-порта-tcp-ip (по умолчанию MySQL использует порт 3306),
затем нажмите клавишу <Enter> несколько раз. Если вы не получите сообщение об
ошибке вроде t e l n e t : Unable to connect to remote host: Connection refused
("telnet: Невозможно подключиться к удаленному хосту: Подключение отклонено"),
значит, какая-то другая программа использует порт TCP/IP, который пытается открыть
mysqld. Разберитесь, что это за программа, и отключите ее, или же с помощью опции
—port сообщите mysqld, что он должен использовать другой порт. В этом случае номер
порта также потребуется сообщать всем клиентским программам для подключения к
серверу через TCP/IP.
Другая причина, по которой порт оказывается недоступным, может быть связана с
брандмауэром, которые блокирует соединения с портом. Если это так, измените на-
стройки брандмауэра, чтобы разрешить доступ к требуемому порту.
Если сервер запускается, но вы не можете подключиться к нему, убедитесь в наличии
в файле /etc/hosts такой строки:
127.0.0.1 localhost
Эта проблема возникает только в системах, которые не имеют работающей библио-
теки поддержки потоков и для которых MySQL должен быть сконфигурирован с под-
держкой MIT-pthreads.
Если вы не можете заставить mysqld стартовать, попытайтесь создать трассировоч-
ный файл, чтобы затем найти причину проблемы, запустив mysqld с опцией —debug.

2.4.5. Защита начальных учетных записей MySQL


Частью процесса установки MySQL является настройка базы данных mysql, содер-
жащей таблицы привилегий:
• Дистрибутивы MySQL для Windows включают предварительно инициализиро-
ванные таблицы привилегий, которые устанавливаются автоматически.
• В Unix таблицы привилегий заполняются сценарием mysql_install_db. При неко-
торых способах установки он запускается автоматически, другие способы требу-
ют, чтобы этот сценарий запускался вручную. Детали можно найти в разделе
2.4.2.
150 Глава 2. Установка MySQL

Таблицы привилегий определяют начальные пользовательские учетные записи


MySQL и их права доступа. Эти учетные записи настраиваются следующим образом:
• Создаются две учетных записи с именем root. Это администраторы, которым раз-
решено делать все. Первоначально с ними связаны пустые пароли, поэтому любой
может подключиться к серверу MySQL как root без пароля и получить все приви-
легии.
• В Windows одна учетная запись root служит для подключения с локального
хоста, а другая - для подключения с любого хоста.
• В Unix обе учетных записи root предназначены для подключения с локально-
го хоста. Подключения должны выполняться с локального хоста путем указа-
ния в качестве имени хоста localhost для одной записи и реального имени
хоста или IP-адреса - для другой.
• Создаются две учетных записи анонимных пользователей, каждая с пустым име-
нем и паролем. Любой может их использовать для подключения к серверу
MySQL.
• В Windows одна анонимная учетная запись предназначена для подключения с
локального хоста. Она имеет все привилегии, как и root. Другая анонимная
учетная запись служит для подключения с любого хоста, имеет все привилегии
только в базе данных test или других базах, имена которых начинаются с test__.
• В Unix обе анонимных учетных записи предназначены для подключения с ло-
кального хоста. Подключения выполняются с локального хоста с указанием
имени localhost для одной учетной записи и реального имени хоста или IP-
адреса - для другой. Эти учетные записи имеют все привилегии в базе данных
t e s t и во всех базах, имя которых начинается с t e s t .
Как упоминалось ранее, ни одна из начальных учетных записей не имеет пароля. Это
значит, что ваша установка MySQL не защищена, пока вы сами не позаботитесь об этом:
• Если вы хотите предотвратить подключения анонимных пользователей без паро-
ля, вы должны либо присвоить им пароль, либо вообще удалить такие записи.
• Вы должны присвоить пароль пользователям root.
Представленная ниже инструкция регламентирует процесс присвоения паролей на-
чальным учетным записям MySQL - сначала анонимным, затем root. Замените "яо-
вый_пароль" в примерах реальным паролем, который хотите использовать. Инструкция
также объясняет, как удалить анонимные учетные записи, если вы предпочтете не иметь
с ними дела.
Вы можете отложить установку паролей на более поздний период, если они не нуж-
ны на время дополнительной настройки и тестирования. Однако обязательно установите
их до начала реальной работы с СУБД.
Для установки паролей учетным записям анонимных пользователей применяется ли-
бо оператор SET PASSWORD, либо оператор UPDATE. В обоих случаях обязательно зашиф-
руйте пароли с помощью функции PASSWORD ().
Чтобы установить пароли под Windows, выполните следующие команды:
shell> mysql -u root
mysql> SET PASSWORD FOR " @'localhost 1 = PASSWORD (' новый_пароль ' ) ;
mysql> SET PASSWORD FOR "@'%' = PASSWORD('новый пароль');
2.4. Настройки и тестирование после установки 151

Для установки паролей под Unix служат такие команды:


s h e l l > mysql -u r o o t
1
mysql> SET PASSWORD FOR ' •§ ' l o c a l h o s t = PASSWORD (' новый_пароль ' ) ;
mysql> SET PASSWORD FOR '•§'имя_хоста* = PASSWORD('новый_пароль');
Во втором операторе SET PASSWORD замените имя_хоста на актуальное имя хоста сер-
вера. Это имя, указанное в столбце Host записи, отличной от l o c a l h o s t , для r o o t в таб-
лице u s e r . Если имя хоста вам не известно, выполните следующую команду перед SET
PASSWORD:
mysql> SELECT Host, User FROM m y s q l . u s e r ;
Найдите запись, в которой значение столбца User равно r o o t , а значение Host отли-
чается от l o c a l h o s t . Затем используйте это значение Host во втором операторе SET
PASSWORD.
Другой способ назначения паролей анонимным учетным записям заключается в при-
менении UPDATE для непосредственной модификации таблицы user. Подключитесь к
серверу как пользователь r o o t и выполните оператор UPDATE для установки значений в
столбце Password в соответствующих записях таблицы user. Процедура одинакова для
Windows и Unix. Следующий оператор UPDATE присваивает пароль обоим анонимным
пользователям одновременно:
s h e l l > mysql -u r o o t
mysql> UPDATE m y s q l . u s e r SET Password = PASSWORD('newpwd')
-> WHERE User = ' ' ;
mysql> FLUSH PRIVILEGES;
После того, как вы обновите пароли непосредственно в таблице, используя UPDATE,
нужно дать команду серверу перечитать таблицу привилегий с помощью FLUSH
PRIVILEGES. В противном случае изменения не вступят в силу, пока сервер не будет пе-
регружен.
Если вы предпочитаете вместо этого удалить анонимные учетные записи, выполните
следующие команды:
s h e l l > mysql -u r o o t
mysql> DELETE FROM m y s q l . u s e r WHERE User = ";
mysql> FLUSH PRIVILEGES;
Оператор DELETE применим как для Windows, так и для Unix. В среде Windows, если
вы хотите удалить только ту анонимную учетную запись, которая имеет те же привиле-
гии, что и r o o t , вместо приведенного выше выполните такие операторы:
s h e l l > mysql -u r o o t
1
mysql> DELETE FROM m y s q l . u s e r WHERE H o s t = ' l o c a l h o s t AND User = ' ' ;
mysql> FLUSH PRIVILEGES;
Эта учетная запись имеет анонимный доступ с полными привилегиями, поэтому ее
удаление повышает безопасность системы.
Присвоить пароли пользователям r o o t можно также различными способами. Ниже
продемонстрированы три метода:
• Использование оператора SET PASSWORD.
• Использование клиентской утилиты командной строки mysql admin.
• Использование оператор UPDATE.
152 Глава 2. Установка MySQL

Чтобы назначить пароли с помощью SET PASSWORD, подключитесь к серверу от имени


root и выполните два оператора SET PASSWORD. He забудьте зашифровать пароли с по-
мощью функции PASSWORD ().
В среде Windows выполните следующее:
shell> mysql -u root
mysql> SET PASSWORD FOR 'root1@'localhost1 = PASSWORD('новый_пароль');
mysql> SET PASSWORD FOR 'root' @' %' = PASSWORD('новый_пароль');
В среде Unix воспользуйтесь такими операторами:
s h e l l > mysql -u root
m y s q l > SET PASSWORD FOR ' r o o t 1 @ ' l o c a l h o s t 1 = P A S S W O R D ( ' н о в ы й _ п а р о л ь ' ) ;
mysql> SET PASSWORD FOR 'root'@'имя_хоста' = PASSWORD('новый_пароль');
Во втором операторе SET PASSWORD замените имя_хоста актуальным именем хоста
вашего сервера. Это то же имя, которое вы использовали, когда присваивали пароли
анонимным пользователям.
Чтобы назначить пароли пользователям root с помощью утилиты mysqladmin, вы-
полните следующие команды:
shell> mysqladmin -u root password "новый_пароль"
shell> mysqladmin -u root -h имя__хоста password "новый_пароль"
Эти команды применимы и для Windows, и для Unix. Во второй команде замените
имя_хоста актуальным именем хоста вашего сервера. Двойные кавычки, обрамляющие
новый пароль, не всегда обязательны, их нужно применять, если пароль содержит пробелы
или другие символы, которые командный интерпретатор трактует как специальные.
Если вы используете очень старую версию сервера MySQL, команда mysqladmin мо-
жет завершиться с сообщением об ошибке parse error near 'SET password' (ошибка
разбора вблизи 'SET password'). Для решения этой проблемы выполните модернизацию
сервера до более новой версии MySQL.
Можно также с помощью оператора UPDATE провести непосредственную модифика-
цию таблицы USER. В следующем примере с его помощью присваиваются пароли обоим
пользователям root одновременно:
s h e l l > mysql -u root
mysql> UPDATE mysql.user SET Password = PASSWORD('новый_пароль')
-> WHERE User = ' r o o t ' ;
mysql> FLUSH PRIVILEGES;
Оператор UPDATE применим и для Windows, и для Unix.
После установки пароли потребуется вводить при каждом подключении к серверу.
Например, если вы хотите с помощью mysqladmin остановить сервер, вы должны делать
это, используя следующую команду:
shell> mysqladmin -u root -p shutdown
Enter password: (enter root password here)
Введите пароль: (введите здесь пароль для root)
; На заметку!
v Если вы забыли пароль пользователя root после его присвоения, процедура его переустановки
'„ описана в разделе А.4.1.
Для настройки новой пользовательской учетной записи применяется оператор GRANT.
За подробными инструкциями обращайтесь в раздел 4.5.2.
2.5. Модернизация MySQL и возврат к старой версии 153

2.5. Модернизация MySQL и возврат


к старой версии
В качестве общего правила, мы рекомендуем при обновлении MySQL от одной серии
выпусков к другой, переходить непосредственно к следующей серии, а не пропускать
их. Например, если вы эксплуатируете MySQL 3.23 и хотите обновить его до более но-
вой серии, устанавливайте MySQL 4.0, а не 4.1 или 5.0.
Ниже приведен список действий, которые следует выполнять всякий раз перед мо-
дернизацией программного обеспечения MySQL:
• Изучите в онлайновом руководстве журнал изменений серии того выпуска, кото-
рый собираетесь установить, чтобы узнать, какие новые средства можно исполь-
зовать. Например, перед обновлением MySQL 4.1 до MySQL 5.0 ознакомьтесь с
новыми позициями. См. http://dev.mysql.com/doc/mysql/en/News.html.
• Прежде чем приступать к обновлению, создайте резервные копии всех баз данных.
• Если вы пользуетесь MySQL под Windows, прочитайте раздел 2.5.7.
• Обновление может потребовать изменений в таблицах привилегий, которые хра-
нятся в базе данных mysql. Иногда, для поддержки новых средств, в них добавля-
ются новые столбцы, а в базу данных - таблицы. Чтобы воспользоваться преиму-
ществами этих новых средств, убедитесь, что ваши таблицы привилегий обновле-
ны. Процедура модернизации таблиц привилегий описана в разделе 2.5.8.
• Если вы применяете репликацию, просмотрите раздел 5.6.
• Если вы устанавливаете дистрибутив MySQL-Max, который включает в себя сер-
вер mysql-max, а затем выполняете его модернизацию до версии, отличной от
MySQL-Max, имейте в виду, что mysqld_safe по-прежнему будет пытаться запус-
кать сервер mysql-max. В этом случае нужно вручную удалить старый сервер
mysql-max, чтобы гарантировать, что mysqld_saf e запустит новый сервер mysqld.
Вы всегда можете перемещать форматы файлов MySQL и файлы данных между раз-
ными версиями в рамках одной и той же архитектуры до тех пор, пока остаетесь в пре-
делах одной серии выпусков MySQL. Текущей рабочей серией выпусков является
MySQL 4.O. Если вы меняете набор символов при запуске MySQL, то должны выпол-
нить myisamchk -r -q —set-character- set=набор^символов на всех таблицах My ISAM. В
противном случае индексы могут быть построены в неправильном порядке, поскольку
смена набора символов также может изменить порядок сортировки.
Если вы переходите от одной серии выпусков к другой (как вверх, так и вниз), то
можете столкнуться с несовместимостью в формате хранения таблиц. В этом случае пе-
ред модернизацией можно с помощью mysqldump построить дампы таблиц. После об-
новления загрузите дампы и с использованием mysql пересоздайте эти таблицы.
Если вы подходите с осторожностью к переходу на новые версии, вы всегда можете
переименовать старый сервер mysqld и только затем устанавливать новый. Например,
если вы применяете MySQL 4.0.18 и хотите перейти на версию MySQL 4.1.1, переиме-
нуйте существующую программу сервера mysqld на mysqld-4.0.18. Если выяснится, что
новый mysqld делает что-то не так, можно просто остановить его и запустить старый.
Если после обновления вы сталкиваетесь с проблемами при перекомпиляции клиент-
ских программ, такими как "Commands out of sync" (Команды не синхронизируются)
или неожиданными выдачами дампа ядра, возможно, это означает, что при компиляции
154 Глава 2. Установка MySQL

вы использовали старые библиотеки ли файлы заголовков. Проверьте даты файла


mysql.h и библиотеки libmysqlclient.a, чтобы убедиться, что они относятся к новому
дистрибутиву MySQL. Если нет, перекомпилируйте свои программы с новыми файлами
заголовков и библиотек.
В случае возникновения проблем, таких как невозможность запуска сервера mysqld
или невозможность подключения без пароля, проверьте, не остался ли у вас файл my.cnf
от прежней установки. Это можно сделать с помощью опции —print-defaults (напри-
мер, mysqld —print-defaults). Если это выведет на экран что-то кроме имени про-
граммы, значит, у вас есть активный файл my. cnf, который влияет на функционирование
сервера или клиентов.
Неплохо выполнять повторную сборку и установку модуля Perl DBD: :mysql при каж-
дой установке нового выпуска MySQL. To же касается и других интерфейсов MySQL,
например, модуля Python MySQLdb.

2.5.1. Модернизация версии 4.1 до 5.0


При модернизации MySQL 4.1 до версии 5.0 потребуется выполнить следующие дей-
ствия:
• Прочитайте о новых средствах версии MySQL 5.0 в онлайновом руководстве
(http://dev.mysql.com/doc/mysql/en/News.html).
• Если вы работаете в MySQL под Windows, прочитайте раздел 2.5.7.
• В MySQL 5.0 добавлена поддержка хранимых процедур. Это требует наличия
таблицы ргос в базе данных mysql. Чтобы ее создать, запустите сценарий
mysqlf ix_privilege_tables, как описано в разделе 2.5.8.
• Если вы применяете репликацию, просмотрите раздел 5.6.

2.5.2. Модернизация версии 4.0 до 4.1


При модернизации MySQL 4.0 до версии 4.1 потребуется выполнить следующие дей-
ствия:
• Проверьте позиции в приведенном далее списке изменений на предмет того, мо-
гут ли они затронуть ваши приложения.
• Прочитайте о новых средствах версии 4.1 в онлайновом руководстве
(http://dev.mysql.com/doc/mysql/en/News.html).
• Если вы работаете в MySQL под Windows, прочитайте раздел 2.5.7.
:
" "' На заметку!
Ранние дистрибутивы альфа-версий MySQL 4.1 для Windows не содержали программы установ-
ки. За подробной информацией обращайтесь в раздел 2.2.1.2.

• После обновления внесите изменения в структуру таблиц привилегий, которые


теперь имеют более длинный столбец Password, необходимый для более безопас-
ной работы с паролями. Процедура включает запуск mysql_f ix_privilege_tables,
как описано в разделе 2.5.8. Реализация изменений в работе приложений с паро-
лями рассматривается далее в настоящем разделе.
• Если вы применяете репликацию, прочитайте раздел 5.6.
2.5. Модернизация MySQL и возврат к старой версии 155

• Обработчик таблиц Berkley DB обновлен до версии DB 4.1 (от 3.2) и поддержива-


ет теперь новый формат журналов. Если вы захотите вернуться к версии 4.0, то
должны будете с помощью mysqdump построить дампы своих таблиц BDB в тексто-
вом формате и удалить все файлы log.XXXXXXXXXX, а только затем запускать
MySQL 4.0 и загружать данные.
• Усовершенствована поддержка наборов символов. Если в столбцах ваших таблиц
хранится информация в одном из наборов данных, которые поддерживаются сер-
вером 4.1 непосредственно, вы можете преобразовать их в соответствии с приве-
денными ниже инструкциями.
• Если вы пользуетесь старым модулем DBD-mysql (Msql-MySQL-modules), то долж-
ны обновить его. Все версии модуля DBD-mysql выше 2.хх должны подходить. Ес-
ли этого не сделать, некоторые методы (наподобие DBl->do ()) не смогут коррект-
но обрабатывать ошибочные ситуации.
Некоторые аспекты поведения в MySQL 4.1 по сравнению с MySQL 4.0 были изме-
нены, чтобы исправить критические ошибки и обеспечить большую совместимость со
стандартом SQL. Эти изменения могут затронуть ваши приложения.
Часть функций MySQL 4.1 можно протестировать в версии MySQL 4.0 до проведе-
ния полной модернизации. В последних выпусках (начиная с 4.0.12) к mysqld была до-
бавлена опция —new (см. раздел 4.2.1).
Упомянутая опция вводит в действие наиболее критичные изменения версии 4.1. Вы
также можете включить их для отдельного клиентского соединения с помощью команды
SET @@new=l и выключить-с помощью команды SET @@new=0.
Если вы считаете, что изменения в версии 4.1 затронут ваши приложения, мы реко-
мендуем до перехода на версию 4.1 загрузить самый последний выпуск MySQL 4.0 и
запустить его с опцией —new, добавив в конфигурационный файл следующие строки:
[mysqld-4.0]
new
Поступая подобным образом, вы можете протестировать новое поведение в версии
4.0 и проверить, работают ли с ним существующие приложения. Это поможет обеспе-
чить более гладкий и безболезненный переход, когда позже вы соберетесь осуществлять
полную модернизацию до версии MySQL 4.1.
Помещение опции --new в раздел [mysqld-4.0] гарантирует, что позже вы не запус-
тите случайно MySQL 4.1 с опцией —new.
В следующем списке описываются изменения, которые могут затронуть приложения,
и на которые следует обратить особое внимание при переходе на версию 4.1.
Изменения в сервере:
• Все таблицы и символьные столбцы теперь имеют ассоциированный с ними сим-
вольный набор. Информация о нем выводится командой SHOW CREATE TABLE и
программой mysqldump. (В MySQL версии 4.0.6 и выше можно читать новые фай-
лы дампов, в более старых версиях - нет.) Это изменение не должно затронуть
приложения, которые работают только с одним набором символов.
• Обычно сервер работает, используя по умолчанию набор символов l a t i n l . Если
вы сохраняете данные столбцов, которые используют другой набор символов из
числа тех, что сервер MySQL 4.1 поддерживает напрямую, то можете их конвер-
тировать. Однако вы должны избегать попыток прямого преобразования из
156 Глава 2. Установка MySQL

l a t i n l в "реальный" набор символов. Это может привести к потере данных. Вме-


сто этого преобразуйте столбец в бинарный тип, а затем из бинарного в небинар-
ный, с требуемым набором символов. Преобразование в бинарный тип и обратно
не приводит к каким-либо изменениям символов и предохраняет данные. Напри-
мер, предположим, что у вас есть таблица MySQL 4.0 с тремя столбцами для хра-
нения значений в символьных наборах latinl, I a t i n 2 n u t f 8 :
CREATE TABLE t
(
latinl_col CHAR(50),
Iatin2_col CHAR(IOO),
utf8_col CHAR(150)
);
После модернизации до версии 4.1 необходимо преобразовать эту таблицу таким
образом, чтобы оставить latinl_col как есть, но изменить столбцы Iatin2_col и
utf 8_col, чтобы они имели наборы символов Iatin2 и utf 8 соответственно. Сна-
чала создайте резервную копию вашей таблицы, затем преобразуйте столбцы:
ALTER TABLE t MODIFY I a t i n 2 _ c o l BINARY(100);
ALTER TABLE t MODIFY u t f 8 _ c o l BINARY(150);
ALTER TABLE t MODIFY I a t i n 2 _ c o l CHAR(100) CHARACTER SET I a t i n 2 ;
ALTER TABLE t MODIFY u t f 8 _ c o l CHAR(150) CHARACTER SET u t f 8 ;

Первые два оператора "изымают" информацию о наборе символов из столбцов


Iatin2_col и utf 8_col. Следующие два оператора назначают им требуемые набо-
ры символов.
Если хотите, можете скомбинировать преобразование к бинарному типу и обрат-
но в одном операторе:
ALTER TABLE t
MODIFY I a t i n 2 _ c o l BINARY(100),
MODIFY u t f 8 _ c o l BINARY(150);
ALTER TABLE t
MODIFY I a t i n 2 _ c o l CHAR(100) CHARACTER SET I a t i n 2 ,
MODIFY u t f 8 _ c o l CHAR(150) CHARACTER SET u t f 8 ;

• Формат определения таблиц, используемый в файлах . frm, был слегка изменен в


версии MySQL 4.1. Версии MySQL 4.0, начиная с выпуска 4.0.11, могут читать
новый формат . frm напрямую, более старые - нет. Если вы хотите провести пере-
нос таблиц из версии 4.1 в верии, предшествующие 4.0.11, то должны воспользо-
ваться mysqldump. См. раздел 7.8.
/ На заметку!
U Если производится модернизация сервера MySQL до версии 4.1.1 или выше, очень трудно будет
;;: вернуться к версии 4.0 или 4.1.0. Это связано с тем, что в ранних версиях для таблиц InnoDB не
|/ поддерживались табличные пространства.

• Если вы запускаете более одного сервера на одной Windows-машине, то должны


использовать разные значения опции —shared-memory-base-name для каждого
сервера.
• Интерфейс агрегатных UDF-функций немного изменился. Теперь вы должны объ-
являть функцию xxx_clear () для каждой агрегатной функции XXX ().
2.5. Модернизация MySQL и возврат к старой версии 157

Изменения в клиентах:
• mysqldump теперь имеет опции --opt и —quote-names, включенные по умолча-
нию. Вы можете выключить их с помощью —skip-opt и --skip-quote-names.
Изменения в SQL:
• Сравнение строк теперь работает в соответствии с требованиями стандарта SQL:
вместо удаления завершающих пробелов перед сравнением, более короткая стро-
ка теперь дополняется пробелами. Однако в связи с этим появилась проблема, что
' а' > f a \ t ' , чего ранее не было. Если у вас есть таблицы со столбцами типа CHAR
или VARCHAR, в которых завершающий символ может быть меньше, чем ASCII (32),
вы должны использовать в отношении них REPAIR TABLE или myisamchk, чтобы
гарантировать корректность этих таблиц.
• В многотабличных операторах DELETE вместо имен таблиц, из которых нужно
удалять, должны использоваться псевдонимы. Например, вместо DELETE t e s t
FROM t e s t AS t l , test2 WHERE . . . следует использовать:
DELETE t l FROM test AS t l , test2 WHERE . . .
• TIMESTAMP теперь возвращается в виде строки в формате Y ' YYY-MM-DD HH:MM:SS\
(Начиная с версии 4.0.12, может быть использована опция —new, чтобы заставить
сервер 4.0 вести себя подобно 4.1.) Если вы хотите получить результат в виде
числа (как это делает 4.0), то должны добавлять в запросах к имени столбца +0:
mysql> SELECT ts_col + О FROM tbl_name;
Отображаемая ширина столбцов TIMESTAMP больше не поддерживается. Напри-
мер, если вы объявили столбец как TIMESTAMP (10), то (10) игнорируется.
Эти изменения были необходимы для обеспечения совместимости со стандартом
SQL. В будущих версиях будут внесены и дальнейшие изменения (обратно со-
вместимые с этим), позволяющие длине столбцов TIMESTAMP отражать требуемое
количество разрядов в долях секунды.
• Двоичные значение, такие как OxFFDF, теперь рассматриваются как строки, а не
числа. Это решает некоторые проблемы с символьными наборами, когда удобно
вводить строки как бинарные значения. В связи с этим изменением вы должны
использовать CAST (), если хотите сравнивать двоичные значения как целые числа:
mysql> SELECT CAST(0xFEFF AS UNSIGNED INTEGER)
-> < CAST(0xFF AS UNSIGNED INTEGER);
-> 0
Если не применять CAST (), выполняется лексикографическое сравнение:
mysql> SELECT OxFEFF < OxFF;
-> 1
Использование двоичных значений в числовом контексте или сравнение их с по-
мощью операции = должно работать как ранее. (Начиная с версии 4.0.13, может
быть использована опция --new, чтобы заставить сервер 4.0 вести себя подобно
4.1.)
• Для функций, которые возвращают значения типа DATE, DATETIME и TIME, тип воз-
врата приведен к единому временному типу. Например, в MySQL 4.1 вы получите
такой результат:
158 Глава 2. Установка MySQL

mysql> SELECT CAST('2001-1-1' AS DATETIME);


-> '2001-01-01 00:00:00'
В MySQL 4.0 результат отличается:
mysql> SELECT CAST('2001-1-1' AS DATETIME);
-> '2001-01-01'
• Значения DEFAULT больше не могут быть указаны для столбцов AUTO_INCREMENT (в
версии 4.0 DEFAULT игнорируется, в версии 4.1 вызывает ошибку).
• LIMIT не принимает отрицательных значений. Используйте какое-нибудь большое
значение (максимум 18446744073709551615) вместо - 1 .
• SERIALIZE больше не является корректным значением режима для переменной
sql_mode. Вместо этого вы должны использовать SET TRANSACTION ISOLATION
LEVEL SERIALIZABLE. SERIALIZE не является допустимым значением и для опции
--sql-mode сервера mysqld. Используйте вместо этого --transaction-isolation=
SERIALIZABLE.
Изменения в API-интерфейсе С:
• Некоторые вызовы API-интерфейса С, такие как mysql_real_query(), в случае
ошибки теперь возвращает 1, а не - 1 . Вам придется изменить некоторые старые
приложения, если они содержат нечто вроде:
if (mysql_real_query(mysql_object, query, query_length) == -1)
{
printf("Ошибка");
}
Измените вызов, чтобы осуществлялась проверка на ненулевое значение:
if (mysql_real_query(mysql_object, query, query_length) != 0)
{
printf("Ошибка");
}
Изменения в работе с паролями
Механизм хеширования паролей в версии MySQL 4.1 изменился, чтобы обеспечивать
более надежную защиту, но это может приводить к проблемам совместимости, если у
вас есть клиентские программы, использующие клиентскую библиотеку из версии 4.0
или предшествующих версий. (Это весьма вероятно, если у вас есть клиенты 4.0, кото-
рые подключаются с удаленных хостов, еще не обновленных до версии 4.1). В представ-
ленном ниже списке предложены некоторые возможные стратегии модернизации. Они
представляют различные компромиссы между требованием обеспечения совместимости
со старыми клиентами и требованиям к повышению безопасности.
• Модернизируются только клиенты, чтобы использовались клиентские библиотеки
версии 4.1. Поведение не меняется (кроме возвращаемых значений для некоторых
вызовов API), вы не можете воспользоваться никакими новыми средствами, пред-
лагаемыми новым клиент-серверным протоколом. (В MySQL 4.1 реализован рас-
ширенный протокол, который предлагает такие возможности, как предварительно
подготовленные SQL-операторы и множественные результирующие наборы.)
• Модернизируется все до версии 4.1 и запускается сценарий mysql_f ix_privilege_tables,
расширяющий размер столбца Password таблицы user для хранения длинных хе-
2.5. Модернизация MySQL и возврат к старой версии 159

шированных паролей. Однако сервер запускается с опцией —old-passwords для


обеспечения обратной совместимости, позволяющей клиентам старых версий
подключаться к их коротко-хешированным учетным записям. В конце концов, ко-
гда все клиенты будут обновлены до версии 4.1, можно прекратить запускать сер-
вер с опцией —old-passwords. Придется также изменить пароли всех учетных за-
писей MySQL для использования более безопасного нового формата.
• Модернизируется все до версии 4.1 и запускается сценарий mysqlf ixprivilegetables,
расширяющий размер столбца Password таблицы user для хранения длинных хе-
шированных паролей. Если вы знаете, что все клиенты уже обновлены до версии
4.1, не запускайте сервер с опцией —old-passwords. Вместо этого измените паро-
ли существующих учетных записей, чтобы они использовали новый формат. Пол-
ностью совместимая с версией 4.1 установка является наиболее безопасной.
Более подробно о хешировании паролей в контексте аутентификации пользователей
и операций смены пароля можно почитать в разделах 4.4.9 и А.2.3.

2.5.3. Модернизация версии 3.23 до 4.0


При модернизации MySQL 3.23 до версии 4.0 потребуется выполнить следующие
действия:
• Проверьте позиции в приведенном далее списке изменений на предмет того, мо-
гут ли они затронуть ваши приложения.
• Прочитайте о новых средствах версии 4.0 в онлайновом руководстве
(http://dev.mysql.com/doc/mysql/en/News.html).
• Если вы работаете в MySQL под Windows, прочитайте раздел 2.5.7.
• После модернизации обновите таблицы привилегий, добавив новые привилегии и
средства. Эта процедура предполагает запуск сценария mysql_f ix_privilege_tables
и подробно описана в разделе 2.5.8.
• Если вы применяете репликацию, прочитайте раздел 5.6.
• Отредактируйте все сценарии запуска MySQL или файлы опций, чтобы нигде не
использовались устаревшие опции, описанные далее в настоящем разделе.
• Преобразуйте старые файлы ISAM в My ISAM. Единственный способ сделать это -
запустить сценарий mysql_convert_table_format. (Этот сценарий реализован на
языке Perl; он требует, чтобы был установлен DBI). Для преобразования таблиц
конкретной базы данных выполните такую команду:
shell> mysql_convert_table_format database имя_базы_данных
Имейте в виду, что это должно быть сделано, только если все таблицы в данной
базе являются таблицами ISAM или My ISAM. Чтобы избежать преобразования таб-
лиц других типов, вы можете явно перечислить имена таблиц ISAM в командной
строке после имени базы данных.
Отдельные таблицы могут быть преобразованы к My ISAM с помощью следующего
оператора ALTER TABLE, который должен выдаваться для каждой из таких таблиц:
mysql> ALTER TABLE имя^таблицы TYPE=MyISAM;
Если вы не уверены насчет типа конкретной таблицы, воспользуйтесь командой:
mysql> SHOW TABLE STATUS LIKE ' имя_таблицы* ',
160 Глава 2. Установка MySQL

• Убедитесь, что у вас нет каких-то клиентов MySQL, которые используют разде-
ляемые библиотеки (вроде модуля Perl DBD: :mysql). Если такие есть, их потребу-
ется перекомпилировать, потому что структуры данных, от которых зависит
libraysqlclient.so, также изменились. То же касается других интерфейсов
MySQL, например, модуля Python MySQLdb.
MySQL 4.0 будет работать, даже если вы не выполните перечисленных действий, од-
нако вы не сможете использовать новые привилегии доступа MySQL 4.0 и столкнетесь с
проблемами позже, при модернизации до версии MySQL 4.1 или более новой. Формат
файлов ISAM по-прежнему работает в серии MySQL 4.0, но считается устаревшим, по-
этому его поддержка по умолчанию не компилируется. Вместо него должны применять-
ся таблицы My ISAM.
Старые клиенты должны работать с версией 4.0 без проблем.
Даже если вы выполните все описанные выше действия, у вас все равно остается
возможность вернуться к версии MySQL 3.23.52 или более новой, если вы столкнетесь с
проблемами в серии MySQL 4.O. В этом случае необходимо с помощью mysqldump под-
готовить дамп все таблицы, использующих полнотекстовые индексы, и перезагрузить
файл дампа в сервер MySQL 3.23. Это необходимо, поскольку в версии 4.0 используется
новый формат полнотекстовых индексов.
В следующем списке описываются изменения, которые могут повлиять на приложе-
ния, и на которые следует обратить особое внимание при переходе на версию 4.0.
Изменения в сервере:
• MySQL 4.0 имеет множество новых привилегий в таблице mysql.user (см. раздел
4.4.3).
Чтобы заставить новые привилегии работать, необходимо обновить таблицы при-
вилегий. Соответствующая процедура описана в разделе 2.5.8. До тех пор, пока
вы не сделаете этого, все учетные записи будут иметь привилегии SHOW
DATABASES, CREATE TEMPORARY TABLES И LOCK TABLES. П р и в и л е г и и SUPER И EXECUTE
п о л у ч а ю т СВОИ З н а ч е н и я ИЗ PROCESS. REPLICATION SLAVE И REPLICATION CLIENT
берут свои значения из FILE.
Если имеются сценарии, создающие новых пользователей MySQL, может понадо-
биться изменить их так, чтобы они выдавали создаваемым пользователям новые
привилегии. Если вы не применяете команду GRANT в этих сценариях, то это впол-
не подходящий момент, чтобы воспользоваться ею вместо прямого изменения
данных в таблицах привилегий.
Начиная с версии 4.0.2, опция --safe-show-database считается устаревшей
(и больше ничего не делает). См. раздел 4.3.3.
Если вы получаете сообщение об ошибке "Access denied" ("Доступ запрещен")
для новых пользователей в версии 4.0.2 и выше, проверьте, не нужно ли восполь-
зоваться какими-то новыми привилегиями, которые не применялись ранее. В ча-
стности, потребуется привилегия REPLICATION SLAVE (вместо FILE) для новых
подчиненных серверов.
• safe_mysqld переименован в mysqld_safе. Для достижения обратной совместимо-
сти бинарные дистрибутивы иногда включают в себя символические ссылки
safejnysqld, которые указывают на mysqld_safе.
2.5. Модернизация MySQL и возврат к старой версии 161

• Поддержка InnoDB теперь включена в бинарный дистрибутив по умолчанию.


Если вы собираете MySQL из исходных текстов, InnoDB конфигурируется по
умолчанию. Если вы не используете InnoDB и хотите сэкономить память серве-
ра, которая расходуется на поддержку InnoDB, указывайте опцию запуска серве-
ра —skip-innodb. Чтобы скомпилировать MySQL без поддержки InnoDB, запус-
кайте configure с ключом —without-innodb.
• Значения для myisam_max_extra_sort_file_size и myisam_raax_extra sort f i l e size
теперь задаются в байтах (до версии 4.0.3 они указывались в мегабайтах).
• mysqldb теперь имеет опцию —temp-pool, включенную по умолчанию, поскольку
это повышает производительность в средах некоторых операционных системах (в
основном, в Linux).
• Опции mysqldb —skip-locking и —enable-locking переименованы, соответст-
венно, в —skip-external-locking и —external-locking.
• Внешняя системная блокировка файлов MylSAM/lSAM теперь по умолчанию вы-
ключена. Ее можно включить с помощью опции —external-locking. (Однако
большинство пользователей в ней никогда не нуждается.)
• Перечисленные ниже переменные и опции запуска переименованы:
Старое имя Новое имя
myisam_bulk_insert_tree_size bulk_insert__buffer_size
query_cache_startup_type query_cache_type
record_buffer read_buffer_size
record_rnd_buffer read_rnd_buffer_size
sort_buffer sort_buffer_size
warnings log-warnings
—err-log —log-error(для mysqld_safe)

Опции запуска record_buffer, sort_buffer и warnings пока поддерживаются в


MySQL 4.0, но считаются устаревшими.
Изменения в SQL:
• Следующие переменные SQL переименованы:
Старое имя Новое имя
SQL_BIG_TABLES BIG_TABLES
SQL_LOW_PRIORITY_UPDATES LOW_PRIORITY_UPDATES
SQL_MAX_JOIN_SIZE MAX_JOIN_SIZE
SQL_QUERY_CACHE_TYPE QUERY_CACHE_TYPE
Старые имена по-прежнему поддерживаются в MySQL 4.0, однако использовать
их не рекомендуется.
• Вы должны использовать SET GLOBAL SQL_SLAVE_SKIP_COUNTER= число_пропусков
вместо SET SQL_SLAVE_SKIP_COUNTER=число_пропусков.
• SHOW MASTER STATUS теперь возвращает пустой набор, если бинарное протоколи-
рование отключено.
162 Глава 2. Установка MySQL

• SHOW SLAVE STATUS теперь возвращает пустой набор, если подчиненная база дан-
ных не инициализирована.
• SHOW INDEX имеет дополнительных две столбца, которых не было в версии 3.23
(Null и Index_type).
• Изменился формат SHOW OPEN TABLES.
• ORDER BY имя_столбца DESC выводит значения NULL в конце, начиная с версии
MySQL 4.0.11. В версии 3.23 и более ранних выпусках 4.0 так было не всегда.
• CHECK, LOCALTIME и LOCALTIMESTAMP отныне являются зарезервированными словами.
• DOUBLE и FLOAT теперь при хранении учитывают флаг UNSIGNED (ранее для таких
столбцов он игнорировался).
• Результат всех бинарных операций (|, &, « , » и ~) теперь целое число без знака.
Это может вызвать проблемы, если вы применяете эти операции в контексте, в
котором ожидается результат со знаком.
Щ На заметку!
;
fy Когда выполняется вычитание целых чисел, причем одно из них UNSIGNED, результат будет без-
\yl знаковым. Другими словами, прежде чем модернизировать сервер до версии MySQL 4.0, необ-
|| ходимо проверить существующие приложение на случаи вычитания из беззнакового целого,
Щ когда ожидается отрицательное значение, или вычитания беззнакового целого из целочислен-
':;г- ного столбца. Вы можете отключить такое поведение с помощью опции —sql-mode=
£' NO_UNSIGNED_SUBSTRACTION при запуске mysqld. См. раздел 4.2.2.

• Вы должны использовать целые для хранения значений столбцов BIGINT (вместо


строк, как это было в MySQL 3.23). Применение строк по-прежнему работает, но
использование целых более эффективно.
• В MySQL 3.23 оператор INSERT INTO.. .SELECT всегда предполагал IGNORE вклю-
ченным. Начиная с 4.0.1, MySQL по умолчанию остановит (и, возможно, осуще-
ствит откат) выполнение оператора в случае ошибки, если только не указать
IGNORE ЯВНО.

• Вы должны использовать TRUNCATE TABLE, когда хотите удалить все строки таб-
лицы и не нуждаетесь в их подсчете. (DELETE FROM имя_таблицы возвращает в вер-
сии 4.0 количество удаленных записей, a TRUNCATE TABLE работает быстрее.)
• При попытке выполнить TRUNCATE TABLE или DROP DATABASE, когда существуют
активные транзакции или блокировки таблиц, вы получите ошибку.
• Чтобы использовать полнотекстовый поиск MATCH.. .AGAINST (...IN BOOLEAN
MODE) в ваших таблицах, необходимо пересоздать их индексы с помощью REPAIR
TABLE имя_таблицы USE_FRM. Если попытаться применить булевский полнотек-
стовый поиск без такого пересоздания индексов, получится неверный результат.
• Функции LOCATE () и INSTR () чувствительны к регистру, если одним из аргумен-
тов является бинарная строка. В других случаях упомянутые функции к регистру
не чувствительны.
• Функция STRCMP () при сравнении строк теперь использует текущий набор симво-
лов. Это делает сравнение строк по умолчанию чувствительным к регистру, если
только один или оба аргумента не являются бинарными строками.
2.5. Модернизация MySQL и возврат к старой версии 163

• HEX {строка) возвращает символы строка, преобразованные в шестнадцатеричный


формат. Если вы хотите конвертировать десятичное число в шестнадцатеричное,
убедитесь, что HEX () вызывается с числовым аргументом.
• Функция RAND {начальное_значение) в версии 4.0 возвращает другие последова-
тельности чисел, чем в версии 3.23. Это было сделано для дальнейшего проведе-
ния различий между RAND {начальное_значение) и RAND (начальное_значение+1).
• Тип возврата по умолчанию для IFNULL (А, В) стал более "общим" для типов А и
В. (Порядок интерпретации от общего к частному - строка, REAL, INTEGER.)
Изменения в API-интерфейсе С:
• Старые функции mysql_drop_db (), mysql_create_db() и mysql_connect () API-
интерфейса С больше не поддерживаются, если только вы не компилируете
MySQL с CFLAGS=-DUSE_OLD_FUNCTIONS. Однако лучше все-таки вместо этого из-
менить клиентские программы для использования нового API-интерфейса.
• В структуре MYSQL_FIELD тип полей length и max_length изменился с unsigned
int на unsigned long. Это не должно вызывать проблемы, кроме генерации пре-
дупреждений, когда они служат аргументами для семейства функций printf ().
• Многопоточные клиентские программы должны использовать mysql_thread_init ()
и mysql_thread_end().
Другие изменения:
• Если вы хотите перекомпилировать модуль Perl DBD: :mysql, используйте свежую
его версию. Рекомендуется применять версию 2.9003. Версии, предшествующие
1.2218, использовать нельзя, поскольку в них применяется устаревший вызов
mysql_drop_db().

2.5.4. Модернизация версии 3.22 до 3.23


Клиенты MySQL 3.22 и MySQL 3.21 будут работать с сервером MySQL 3.23 без ка-
ких-либо проблем. При модернизации до MySQL 3.23 от более старых версий обратите
внимание на перечисленные ниже изменения.
Изменения таблиц:
• MySQL 3.23 поддерживает таблицы нового типа My ISAM и таблицы старого типа
ISAM. По умолчанию все новые таблицы создаются в формате My ISAM, если только
сервер mysqld не запущен с опцией —default-table-isam. Нет необходимости
конвертировать старые таблицы ISAM для использования их в MySQL 3.23. Одна-
ко вы можете это сделать с помощью оператора ALTER TABLE имя_таблицы
TYPE=MyISAM либо Perl-сценария mysql_convert_table_f ormat.
• Все таблицы, использующие набор символов tis620, должны быть исправлены с
помощью myisamchk -r или REPAIR TABLE.
• Если вы применяете в таблицах ISAM порядок сортировки german, то должны ис-
править их с помощью isamchk -r, потому что мы внесли некоторые изменения в
упомянутый порядок сортировки.
164 Глава 2. Установка MySQL

Изменения в клиентах:
• Стандартный MySQL-клиент mysqld теперь по умолчанию запускается с опцией
—no-named-commands (-g). Ее можно отключить, указав —enable-named-commands (-G).
В некоторых случаях это может привести к проблемам совместимости, например,
в SQL-сценариях, которые используют именованные команды без точек с запятой.
Длинный формат команд по-прежнему работает с первой строки.
• Если вы хотите, чтобы ваши файлы mysqldump были совместимы между версиями
MySQL 3.22 и MySQL 3.23, не следует при запуске mysqldump указывать опции
—opt и — a l l .
Изменения в SQL:
• Если выполнить DROP DATABASE для базы данных, указанной через символическую
ссылку, то удаляется как сама база, так и эта ссылка. Этого не происходило в
MySQL 3.22, потому что configure не мог определить доступность системного
вызова readlink().
• OPTIMIZE TABLE теперь работает только для таблиц My ISAM. Для других типов таб-
лиц с целью оптимизации можно применять ALTER TABLE. Во время выполнения
OPTIMIZE TABLE таблица блокируется, чтобы предотвратить обращение к ней из
других потоков сервера.
• Функции работы с датами, которые имеют дело с частью значения даты (подоб-
ные MONTH()), теперь возвращают 0 для даты 0000-00-00. В MySQL 3.22 они воз-
вращали NULL.
• Тип возврата по умолчанию функции IF () теперь зависит от обоих аргументов, а
не от одного.
• Столбцы AUTO_INCREMENT не должны использоваться для хранения отрицательных
значений. Причина состоит в том, что отрицательные числа приводили к пробле-
мам, когда обращались из -1 в 0. Вы также не должны сохранять значения 0 в
столбцах AUTO_INCREMENT. CHECK TABLE будет предупреждать о значениях 0, по-
скольку они могут измениться, если таблицу выгрузить в дамп и потом загрузить
обратно. AUTO_INCREMENT для таблиц MylSAM теперь обрабатываются на более низ-
ком уровне и значительно быстрее, нежели ранее. Вдобавок, в таблицах My ISAM ста-
рые значения больше не используются, даже если вы удалите строки из таблицы.
• CASE, DELAYED, ELSE, END, FULLTEXT, INNER, RIGHT, THEN И WHEN теперь ЯВЛЯЮТСЯ за-
резервированными словами.
• FLOAT (p) теперь возвращает значение с плавающей точкой, а не с фиксированным
количеством разрядов, как ранее.
• При объявлении столбцов типа DECIMAL [длина, дес_точка) аргумент длина от-
ныне не включает в себя места под знак или десятичную точку.
• Строка TIME должна быть теперь в одном из следующих форматов:
[[[ДЕНЬ] [Ч]Ч:]ММ:]СС[.доли_сек] или [[[[[Ч]Ч]Ч]Ч]ММ]СС[.доли_сек].
• LIKE теперь сравнивает строки, используя те же правила сравнения, что и опера-
ция =. Если нужно вернуть старое поведение, скомпилируйте MySQL с флагом
CXXFLAGS=-DLIKE CMP TOUPPER.
2.5. Модернизация MySQL и возврат к старой версии 165

• Функция REGEXP теперь не чувствительна к регистру, если только аргумент - не


бинарная строка.
• Когда вы проверяете или восстанавливаете таблицы My ISAM (.MYI), то должны ис-
пользовать оператор CHECK TABLE либо команду myisamchk. Для таблиц ISAM
(.ISM) применяйте команду isamchk.
• Проверьте все вызовы DATEFORMAT () на предмет наличия символа '%' перед каж-
дым символом формата. (MySQL 3.22 уже воспринимал такой синтаксис, однако
не требовал его.)
• В MySQL 3.22 вывод SELECT DISTINCT... почти всегда был отсортированным.
Для получения отсортированного вывода в MySQL 3.23 необходимо использовать
GROUP BY ИЛИ ORDER BY.

• SUM() теперь возвращает NULL вместо 0, если нет подходящих строк. Этого требу-
ет стандарт SQL.
• Операции AND или OR со значениями NULL теперь возвращают NULL вместо 0. Это в
основном касается запросов, использующих NOT в выражениях AND/OR как NOT
NULL = NULL.

• Функции LPAD () и RPAD () теперь укорачивают результирующую строку, если она


длиннее, чем аргумент, задающий длину.
Изменения в API-интерфейсе С:
• m y s q l f e t c h f ields_direct () является функцией, а не макросом. Теперь она воз-
вращает указатель на MYSQL_FIELD вместо MYSQL_FIELD.
• mysql_num_fields () не может быть использована в объектах MYSQL* (теперь это
функция, в качестве аргумента принимающая MYSQL__RES*). Сейчас вместо нее с
объектами MYSQL* нужно использовать mysql_field_count ().

2.5.5. Модернизация версии 3.21 до 3.22


Между версиями MySQL 3.21 и MySQL 3.22 не изменилось ничего такого, что отра-
зилось бы на совместимости. Единственной ловушкой можно считать то, что новые таб-
лицы со столбцами типа DATE используют новый способ хранения дат. Вы не сможете
получить доступ к новым столбцам DATE через старый сервер mysqld.
При модернизации более ранних версий до MySQL 3.22 нужно помнить о следую-
щих изменениях:
• После установки версии MySQL 3.22 вы должны стартовать новый сервер и затем
запустить сценарий mysqlf i x p r i v i l e g e t a b l e s . Это добавит новые привилегии,
которые понадобятся для использования в команде GRANT. Если вы забудете об
этом, то получите сообщение Access denied при попытке выполнить ALTER
TABLE, CREATE INDEX или DROP INDEX. Процедура обновления таблиц привилегий
описана в разделе 2.5.8.
• В API-интерфейсе С-функция mysq_real_connect () изменилась. Если у вас есть
старые клиентские программы, которые обращались к этой функции, вы должны
добавить передачу значения 0 для нового аргумента db (или переписать клиенты,
чтобы они передавали реальный элемент db для более быстрого подключения).
Вы также должны вызывать mysql_init() перед вызовом mysq_real__connect ().
166 Глава 2. Установка MySQL

Эти изменения были внесены, чтобы позволить новой функции mysql_options ()


сохранять опции в управляющей структуре MYSQL.
• Переменная mysqld key__buffer переименована в key_buffer_size, однако вы по-
прежнему можете использовать старое имя в файлах запуска.

2.5.6. Модернизация версии 3.20 до 3.21


Если вы работаете с версией сервера, более старой, чем 3.20.28, и хотите перейти на
версию 3.21, потребуется предпринять следующие действия.
Вы можете запускать сервер mysqld версии 3.21 с опцией —old-protocol, чтобы ис-
пользовать его с клиентами из дистрибутива 3.20. В этом случае сервер выполняет ста-
рую проверку password () вместо нового метода. Кроме того, новая клиентская функция
mysql_errno() не вернет никакую из ошибок сервера, а только CR_UNKNOWN_ERROR. С
ошибками клиента эта функция работает.
Если вы не применяете опцию —old-protocol, вам придется выполнить следующие
изменения:
• Весь клиентский код должен быть перекомпилирован. Если вы используете
ODBC, вам понадобится новый драйвер MyODBC 2.x.
• Сценарий scripts/add_long_password должен быть запущен для преобразования
столбца Password таблицы mysql.user в CHAR(16).
• Все пароли в mysql.user должны быть переустановлены, поскольку для них
теперь используется длина в 62, а не 31 разряд.
• Формат таблиц не изменился, поэтому преобразовывать их не нужно.
MySQL 3.20.28 и последующие версии могут работать с новым форматом таблицы
user, никак не затрагивая клиентов. Если вы имеете дело с версией MySQL, предшест-
вующей 3.20.28, после преобразования таблицы user пароли работать перестанут. По-
этому, чтобы соблюсти все меры безопасности, нужно сначала модернизировать сервер,
по крайней мере, до версии MySQL 3.20.28, а затем до версии MySQL 3.21.
Новый клиентский код работает с сервером mysqld 3.20.x, поэтому если вы столкну-
лись с проблемами в версии 3.21.x, то можете вернуться к старому серверу 3.20.x без
повторной компиляции клиентских приложений.
Если не использовать опцию —old-protocol для mysqld, то старые клиенты не смо-
гут подключиться и получат следующее сообщение об ошибке:
ERROR: Protocol mismatch. Server Version = 10 Client Version = 9
ОШИБКА: Н е с о в п а д е н и е протокола. Версия сервера = 1 0 Версия клиента =9
Интерфейс Perl DBI также поддерживают старый интерфейс mysqlperl. Единствен-
ное изменение, которое нужно внести при использовании mysqlperl, касается аргумен-
тов функции connect (). Новые аргументы таковы: host, database, user и password (за-
метьте, что изменились места аргументов user и password).
Следующие изменения могут повлиять на запросы в старых приложениях:
• HAVING теперь необходимо указывать перед конструкцией ORDER BY.
• Параметры LOCATE () поменялись местами.
• Появились новые зарезервированные слова. Наиболее важные из них: DATE,
DATETIME И TIMESTAMP.
2.5. Модернизация MySQL и возврат к старой версии 167

2.5.7. Модернизация MySQL под Windows


Для выполнения модернизации MySQL под Windows, выполните следующие шаги:
1. Загрузите последний дистрибутив MySQL под Windows.
2. Выберите время дня, когда нагрузка на сервер минимальна и допустим перерыв в
обслуживании.
3. Предупредите о перерыве в обслуживании пользователей, которые остаются ак-
тивными.
4. Остановите работающий сервер MySQL (например, командой NET STOP MySQL,
утилитой Services или командой mysqladmin shutdown).
5. Выйдите из программы WinMySQLAdmin, если она работает.
6. Запустите сценарий установки дистрибутива, щелкнув на кнопке Install (Устано-
вить) в окне программы WinZip, и следуйте шагам установки.
у\ На заметку!
\( Ранние дистрибутивы альфа-версий MySQL 4.1 для Windows не содержали программы установ-
•'•';, ки. Инструкции по установке таких дистрибутивов представлены в разделе 2.2.1.2.

7. Вы можете либо перезаписать установку MySQL (обычно расположенную в


C:\mysql), либо установить в другой каталог, например, C:\raysql4. Рекомендует-
ся перезаписать старую установку.
8. Перезапустите сервер, например, с помощью команды NET START MySQL, если он
выполняется как служба, либо напрямую вызвав mysqld.
9. Обновите таблицы привилегий. Эта процедура описана в разделе 2.5.8.
Возможные ошибочные ситуации:
A system error has occurred.
System error 1067 has occurred.
The process terminated unexpectedly.
Возникла системная ошибка.
Возникла системная ошибка 1067.
Процесс неожиданно завершился.
Эти ошибки означают, что ваш файл настроек (по умолчанию C:\my.cnf) содержит
опцию, которую не распознает MySQL. Это можно проверить, попытавшись запустить
сервер после переименования файла опций, чтобы предотвратить его чтение сервером
(например, переименуйте C:\my.cnf в C:\my.cnf.old). Если вы убедитесь, что это так,
нужно будет выявить опцию, которая в этом виновата. Создайте новый файл my.cnf и
перенесите в него по частям содержимое старого файла, каждый раз пытаясь перезапус-
тить сервер до тех пор, пока не обнаружите опцию, из-за которой сервер не смог нор-
мально запуститься.

2.5.8. Обновление таблиц привилегий


Некоторые выпуски вносят изменения в структуры таблиц привилегий (таблицы в
базе данных mysql), добавляя новые привилегии или средства. Дабы иметь уверенность,
что структура ваших таблиц привилегий не устарела при обновлении MySQL, вы долж-
ны их также обновить.
168 Глава 2. Установка MySQL

В системах на базе Unix и Unix-подобных ОС это делается путем запуска сценария


mysql_fix_privilege_tables:
shell> mysql_fix_privilege_tables
Этот сценарий должен выполняться при работающем сервере. Он пытается устано-
вить соединение с сервером, который функционирует на локальном хосте, от имени
root. Если ваша учетная запись root требует пароля, укажите пароль в командной стро-
ке. Для MySQL 4.1 и выше это делается следующим образом:
shell> mysql__fix_privilege_tables —'разз\юхб=пароль_пользователя_гооЬ
Для более ранних версий MySQL это выглядит так:
shell> mysql_fixjprivilege_tables пароль_пользователя_гооЬ
Сценарий mysql_fixjprivilege_tables выполняет все действия, необходимые для
преобразования в новый формат существующих таблиц привилегий. При этом он может
выдать некоторые предупреждения наподобие Duplicate column names (Дублированные
имена столбцов). Их можно проигнорировать.
После завершения этого сценария перезапустите сервер.
В Windows-системах не было простого пути обновить таблицы привилегий до версии
MySQL 4.0.15. Начиная с этой версии, дистрибутив MySQL включает в себя SQL-
сценарий mysql_fix_privilege_tables.sql, который можно запустить с помощью кли-
ента mysql.
Если MySQL находится в каталоге С: \mysql, команды выглядят следующим образом:
С:\> C:\mysql\bin\mysql -u root -p mysql
mysql> SOURCE С:\mysql\scripts\mysql_fix_privilege_tables.sql
Программа mysql запросит у вас пароль для root; введите его. Если ваша установка на-
ходится в другом каталоге, исправьте соответствующим образом команду. Как и при выпол-
нении этой процедуры под Unix, во время работы mysql_fix_privilege_tables.sql могут
быть выданы сообщения типа Duplicate column names. Их также можно проигнорировать.
После завершения этого сценария перезапустите сервер.

2.5.9. Копирование баз данных MySQL на другую машину


Если вы работаете с MySQL 3.23 или предшествующими версиями, можно копиро-
вать файлы .frm, .MYI и .MYD для таблиц MylSAM между различными архитектурами, ко-
торые поддерживают одинаковый формат чисел с плавающей точкой (MySQL позабо-
тится о необходимой перестановке байтов). См. раздел 8.1.
Файлы данных и индексов формата ISAM (.ISD и .ISM соответственно) являются ар-
хитектурно-зависимыми, и в некоторых случаях, зависимыми от операционной системы.
Если вы хотите переместить свои приложения на другую машину, не пытайтесь перене-
сти базы данных простым копированием файлов. Используйте для этого mysqldump.
По умолчанию mysqldump создает файл, содержащий SQL-операторы. Вы можете пе-
ренести этот файл на другую машину и использовать в качестве входного для клиент-
ской программы mysql.
Запустите mysqldump —help, чтобы просмотреть доступные опции. Если вы перено-
сите данные в более новую версию сервера MySQL, то должны использовать mysqldump
—opt, чтобы получить преимущества от оптимизации, результатом которой будет более
компактный файл дампа, который может быстрее обрабатываться.
2.5. Модернизация MySQL и возврат к старой версии 169

Простейший (но не самый быстрый) способ переместить базу данных между двумя
машинами предполагает запуск следующих команды на машине, на которой расположе-
на база данных:
shell> mysqladmin -h 'имя другого хоста* create имя_базы_данных
shell> mysqldump —opt db_name | mysql -h 'имя другого хоста' имя_базы_данных
Если вы хотите скопировать базу данных с удаленной машины через медленную
сеть, можно поступить так:
shell> mysqladmin create имя_базы_данных
shell> mysqldump -h 'имя другого хоста1 —opt —compress имя_базы_данных |
mysql имя_базы_данных
Вы можете также сохранить результат в файле, затем переместить этот файл на дру-
гую машину и там загрузить его в базу данных. Например, вы можете поместить базу
данных в дамп на исходной машине следующим образом:
shell> mysqldump —quick имя_базы_данных | gzip > имя_ базы_ да иных, con ten ts.gz
Файл, полученный подобным образом, является сжатым. Переместите файл, содержа-
щий данные из базы, на целевую машину и выполните там приведенные ниже команды:
shell> mysqladmin create имя_базы_данных
shell> gunzip < имя_базы_данных.contents.gz | mysql имя_базы_данных
Для переноса базы данных можно также использовать mysqldump и mysql import. В
случае больших таблиц это может оказаться значительно быстрее, чем при простом
применении mysqldump. В следующем примере КАТАЛОГ_ДАМПА представляет собой пол-
ное имя пути к каталогу, куда помещается вывод mysqldump.
Вначале создайте каталог для выходных файлов и постройте дамп базы данных:
s h e l l > mkdir КАТАЛОГ_ДАМПА
s h e l l > mysqldump —ЬаЬ=КАТАЛОГ_ДАМПА имя_базы_данных

Затем перенесите файлы из каталога КАТАЛОГ_ДАМПА в какой-нибудь подходящий ка-


талог на целевой машине и загрузите его в MySQL с помощью следующих команд:
shell> mysqladmin create имя_базы_данных #создание базы данных
s h e l l > cat КАТАЛОГ_ДАМПА/*. sql | mysql имя_базы__данных #создание таблиц
#в базе данных
shell> mysqlimport имя_базы_данных КАТАЛОГ_ДАМПА/*. txt #загрузка данных
#в таблицы
Также не забудьте скопировать базу данных mysql, поскольку в ней находятся табли-
цы привилегий user, db и host. Возможно, на новой машине понадобится запускать
команды от имени пользователя root, чтобы получить работающую базу на новом
месйосле импорта базы данных mysql на новую машину необходимо запустить
mysqladmin f lushprivileges, чтобы сервер перезагрузил информацию из таблиц приви-
легий.
170 Глава 2. Установка MySQL

2.6. Замечания по поводу конкретных


операционных систем
2.6.1. Замечания по поводу Linux
В этом разделе обсуждаются некоторые моменты, специфичные для ОС Linux. Пер-
вые несколько подразделов дают общее представление об особенностях и проблемах,
связанных с этой операционной системой, при установке из бинарного или исходного
дистрибутивов, а также постустановочные действия. В остальных подразделах рассмат-
риваются проблемы, связанные с Linux на специфических платформах.
Следует иметь в виду, что большинство описанных проблем возникают в более ста-
рых версиях Linux. Если вы имеете дело с новейшими версиями, вполне вероятно, вы не
столкнетесь ни с одной из них.

2.6.1.1. Замечания по операционной системе Linux


MySQL требует, как минимум, Linux версии 2.0.
Предупреждение
Мы сталкивались с некоторыми странными проблемами с Linux 2.2.14 и MySQL в SMP-системах
(симметричных многопроцессорных системах). У нас также есть некоторые сообщения от поль-
зователей MySQL, у которых возникали серьезные проблемы со стабильной работой MySQL на
ядре 2.2.14. Если вы используете это ядро, обновите его до 2.2.19 (или более нового) или до 2.4.
Если у вас многопроцессорная система, вам нужно всерьез рассмотреть переход на ядро 2.4, по-
скольку это даст ощутимое повышение производительности. Кроме того, ваша система станет
£ более стабильной.

При использовании LinuxThreads вы увидите, по меньшей мере, три работающих про-


цесса mysqld. На самом деле, это не процессы, а потоки. Один из них принадлежит дис-
петчеру LinuxThreads, один обслуживает подключения, и один - сигналы и сообщения.

2.6.1.2. Замечания по бинарным дистрибутивам для Linux


Бинарные дистрибутивы Linux-Intel и RPM-совместимые выпуски MySQL сконфигу-
рированы таким образом, чтобы обеспечить максимально возможную скорость. Мы все-
гда стараемся использовать наиболее быстрые и стабильные доступные компиляторы.
Бинарные выпуски скомпилированы с опцией - s t a t i c , это означает, что, как прави-
ло, вам не нужно беспокоиться о версиях используемых системных библиотек. Также у
вас нет необходимости устанавливать LinuxThreads. Программы, скомпонованные с
ключом - s t a t i c немного больше по размеру, чем скомпонованные динамически, но они
также и несколько быстрее работают (на 3-5%). Однако проблемой статически скомпо-
нованных программ является то, что вы не сможете применять определенные пользова-
телем функции (User-defined functions - UDF). Если вы собираетесь писать или исполь-
зовать UDF (это нечто, предназначенное только для программистов на С и C++), вам
нужно самостоятельно перекомпилировать MySQL с использованием динамической
компоновки.
Известная сложность с бинарными дистрибутивами состоит в том, что в старых
Linux-системах, которые используют libc (таких как Red Hat 4.x и Slackware) можно
столкнуться с некоторыми некритическими проблемами, касающимися преобразования
имен хостов. Если ваша система использует libc вместо glibc2, то вы, вероятно, столк-
нетесь с трудностями при разрешении имен хостов и getpwnam(). Это происходит пото-
му, что, к сожалению, glibc зависит от некоторых внешних библиотек, реализующих
2.6. Замечания по поводу конкретных операционных систем 171

эту функциональность, даже при компоновке с ключом - s t a t i c . Эта проблема проявля-


ется в двух аспектах:
• Возможно, во время выполнения mysql_install_db вы увидите следующее сооб-
щение об ошибке:
Sorry, the host 'xxxx' could not be looked up
Извините, хост 'хххх' не может быть найден
Вы можете справиться с этим, запустив mysql_install_db --force, при этом не
будет выполняться тест resolveip в составе mysql_install_db. Плохая сторона
этого решения заключается в том, что вы не сможете использовать имена хостов в
таблицах привилегий. Вместо них (кроме localhost) придется указывать IP-
адреса.
• При попытке выполнить mysqld с опцией —user вы можете увидеть следующее
сообщение:
getpwnam: No such f i l e or directory
getpwnam: Несуществующий файл или каталог
Чтобы обойти это, запустите mysqld, используя команду su вместо опции —user.
Это вынудит систему изменить пользовательский идентификатор процесса mysqld
и ему не придется делать это самому.
Другой способ решить обе проблемы - не использовать бинарные дистрибутивы. За-
грузите исходный дистрибутив MySQL (в формате RPM или .tar.gz) и установите его
вместо бинарного.
В некоторых системах Linux версии 2.2 вы можете получить сообщение об ошибке
"Resource temporarily unavailable" ("Ресурс временно недоступен"), когда клиенты
устанавливают множество соединений с сервером mysqld через TCP/IP. Эта проблема
объясняется тем, что Linux выдерживает паузу между моментом закрытия TCP/IP-сокета
и моментом, когда система действительно освобождает его. А так как в системе сущест-
вует ограниченное число TCP/IP-cлотов, вы столкнетесь с недостатком ресурсов, если
клиенты пытаются открыть слишком много TCP/IP-соединений за короткое время. Та-
кую ошибку можно увидеть, если запустить тест производительности test-connect че-
рез TCP/IP.
Нас извещали об этой проблеме несколько раз в различных списках рассылки, по-
священных Linux, но мы пока не нашли подходящего решения. Единственный извест-
ный способ исправить это для клиентов - использовать постоянные соединения, или же,
если сервер базы данных и клиенты работают на одной и той же машине, использовать
сокеты Unix вместо TCP/IP-соединений.

2.6.1.3. Замечания по исходным дистрибутивам Linux


Следующие замечания относительно glib с касаются только ситуаций, когда вы со-
бираете MySQL из исходных текстов самостоятельно. Если вы работаете с Linux на ма-
шинах х86, в большинстве случаев гораздо лучше использовать наш бинарный дистри-
бутив. Мы компонуем бинарные программы с самыми последними исправленными вер-
сиями библиотеки glibc, которые можем получить, и с наилучшими комбинациями
опций компилятора, стараясь обеспечить их работоспособность в сильно загруженных
серверах. Для типичного пользователя, даже для установок, в которых осуществляется
множество параллельных клиентских соединений, и размеры таблиц превышают предел
172 Глава 2. Установка MySQL

в 2 Гбайт, наши бинарные сборки являются наилучшим выбором в большинстве случаев.


После прочтения последующего текста, если вы сомневаетесь, что лучше сделать, пер-
вым делом попробуйте наш бинарный дистрибутив, чтобы проверить, удовлетворит ли
он ваши нужды. Если вы обнаружите, что он недостаточно хорош, тогда можете попы-
таться произвести собственную сборку. В этом случае мы будем благодарны за сообще-
ние об этом, чтобы мы смогли сделать лучший вариант в следующий раз.
MySQL под Linux использует LinuxThreads. Если вы работаете со старыми версиями
Linux, в которых нет glibc2, то должны установить LinuxThreads, прежде чем компилиро-
вать MySQL. Вы можете загрузить его с http://dev.mysql.com/downloads/os-linux.htral.
Имейте в виду, что glibc 2.1.1 и предшествующих версий содержит критическую
ошибку в функции pthread_mutex_timedwait (), которая вызывается при выполнении
оператора INSERT DELAYED. Мы рекомендуем не применять INSERT DELAYED до тех пор,
пока не будет обновлена glibc.
Имейте в виду также, что ядро Linux и библиотека LinuxThreads по умолчанию могут
иметь не более 1024 потоков. Если вы планируете иметь более 1000 параллельных под-
ключений, то должны внести некоторые изменения в LinuxThreads:
• Увеличить значение PTHREAD_THREADS_MAX в sysdeps/unix/sysv/linux/bits/local_lim.h
до 4096 и уменьшить STACK_SIZE в linuxthreads/internals .h до 256 Кбайт. Пути
указаны относительно корневого каталога glibc. (Помните, что MySQL не будет
стабильным при 600-1000 соединений, если размер STACKSIZE оставить по умол-
чанию равным 2 Мбайт).
• Перекомпилировать LinuxThreads, чтобы получить новый файл библиотеки
libpthread. а и скомпоновать MySQL еще раз.
Страница http://www.volano.com/linuxnotes.html содержит дополнительную ин-
формацию об ограничениях, накладываемых на потоки LinuxThreads.
Существует другое обстоятельство, которое причиняет ущерб производительности
MySQL, особенно в SMP-системах. Реализация семафоров LinuxThreads в glibc 2.1
очень плоха для программ со множеством потоков, которые удерживают семафоры
только в течение короткого времени. Это приводит к парадоксальным результатам: если
скомпоновать MySQL с LinuxThreads без изменений, то во многих случаях изъятие про-
цессоров в SMP-системах приводит к повышению производительности MySQL. Мы
подготовили соответствующее исправление для glibc 2.1.3, которое доступно по адресу
http://www.mysql.com/Downloads/Linux/linuxthreads-2.1-patch.
MySQL 3.23.36 с glibc 2.2.2 использует адаптированные семафоры, которые значи-
тельно лучше, чем даже исправленные в glibc 2.I.3. Однако надо иметь в виду, что при
некоторых условиях текущий вариант семафоров в glibc 2.2.2 может снижать произво-
дительность MySQL. Вероятность того, что это произойдет, может быть уменьшена,
если с помощью команды nice повысить приоритет процесса mysqld. Мы также готовы
исправить это поведение соответствующим обновлением, которое доступно по адресу
http://www.mysql.com/Downloads/Linux/linuxthreads-2.2.2.patch. Это обновление
комбинирует исправление снижения производительности, максимального количества
потоков и размера стека. Вам понадобится применить его в каталоге linuxthreads ко-
мандой patch -pO </tmp/linuxthreads-2.2.2.patch. Мы надеемся, что это будет вклю-
чено в какой-либо форме в будущие выпуски glibc 2.2. В любом случае, при выпол-
нении компоновки с glibc 2.2.2 потребуется скорректировать STACKSIZE и
PTHREAD_THREADS_MAX. Мы надеемся также, что значения по умолчанию будут исправле-
2.6. Замечания по поводу конкретных операционных систем 173

ны соответствующим образом, дабы обеспечить в будущем надежную работу сильно


загруженных серверов MySQL, так что команды, необходимые для генерации вашей
собственной сборки, будут сводиться лишь к ./configure; make; make i n s t a l l .
Мы советуем использовать эти исправления для сборки специальной версии библио-
теки libpthread.a, и использовать ее только для статической компоновки с MySQL.
Нам известно, что эти исправления безопасны для MySQL и ощутимо повышают его
производительность, но мы ничего не можем сказать насчет других приложений. Если
вы компонуете другие приложения, которые требуют LinuxThreads с исправленной вер-
сией библиотеки, или собираете разделяемую версию этой библиотеки для установки в
своей системе, помните, что вы делаете это на собственный страх и риск.
Если вы сталкиваетесь с любыми странными проблемами во время установки
MySQL, или с зависанием утилит общего применения, весьма вероятно, что это связано
с библиотеками или компилятором. Если причина именно в этом, использование наших
бинарных дистрибутивов должно ее решить.
При компоновке ваших собственных клиентских программ MySQL вы можете столк-
нуться со следующей ошибкой:
l d . s o . l : f a t a l : libmysqlclient,so.#:
open failed: No such f i l e or directory
Избежать этой проблемы можно одним из следующих способов:
• При компоновке клиентских программ вместо -Ьпуть использовать флаг
-W1,г/лолный/лутьЛс/libmysqlclient.so.
• Скопировать libmysqclient.so в /usr/lib.
• Добавить путь к каталогу, в котором находится libmysqlclient. so, в переменную
окружения LDRUNPATH до запуска ваших клиентских программ.
Если вы используете компилятор Fujitsu (f cc/FCC), то у вас будут некоторые пробле-
мы во время компиляции MySQL, поскольку заголовочные файлы Linux сильно ориен-
тированы на дсс. Следующая строка configure должна работать с fcc/FCC:
CC=fcc CFLAGS="-0 -К fast -К l i b -К omitfp -Kpreex -D_GNU_SOURCE \
-DCONST=const -DNO_STRTOLL_PROTO" \
CXX=FCC CXXFLAGS="-0 -K fast -K l i b \
-K omitfp -K preex —no_exceptions — n o _ r t t i -D_GNU_SOURCE \
-DCONST=const -Dalloca= b u i l t i n _ a l l o c a -DNO_STRTOLL_PROTO \
f
-D_EXTERN_INLINE=static _ i n l i n e I M \
./configure \
—prefix=/usr/local/mysql —enable-assembler \
—with-mysqld-ldflags=-all-static —disable-shared \
—with-low-memory

2.6.1.4. Постустановочные процедуры под Linux


Сценарий mysql. server можно найти в подкаталоге support-files каталога установ-
ки MySQL или дерева исходных текстов MySQL. Вы можете установить его как
/etc/init.d/mysql для того, чтобы автоматически стартовать и останавливать сервер
MySQL. См. раздел 2.4.3.
Если MySQL не может открыть файлы или подключений, возможно, Linux не скон-
фигурирован для работы с достаточным количеством файлов.
174 Глава 2. Установка MySQL

В среде Linux 2.2 и выше вы можете проверить количество доступных дескрипторов


файлов следующим образом:
shell> cat /proc/sys/fs/file-max
shell> cat /proc/sys/fs/dquot-max
shell> cat /proc/sys/fs/super-max
Если у вас имеется более 16 Мбайт памяти, вам потребуется добавить приведенные
ниже команды в инициализационные сценарии (например, /etc/init.d/boot.local в
SuSE Linux):
echo 65536 > /proc/sys/fs/file-max
echo 8192 > /proc/sys/fs/dquot-max
echo 1024 > /proc/sys/fs/super-max
Можно также выполнить эти команды из командной строки от имени root, однако
при перезапуске компьютера установки будут утеряны.
В качестве альтернативного варианта эти параметры можно устанавливать при за-
пуске с помощью инструмента sysctl, который применяется во многих дистрибутивах
Linux (в SuSE он добавлен, начиная с версии SuSE Linux 8.0). Просто поместите в файл
/etc/sysctl. conf следующие строки:
# Increase some values for MySQL
# Увеличить некоторые значения для MySQL
fs.file-max = 65536
fs.dquot-max = 8192
fs.super-max = 1024
Вы должны будете также добавить показанные ниже строки в файл /etc/my. cnf:
[mysqld_safe]
open-files-limit=8192
Это установит для сервера ограничение в 8192 подключений и открытых файлов.
Константа LinuxThreads STACK_SIZE управляет размером стека потоков в адресном
пространстве. Необходимо, чтобы она была достаточно большой, дабы обеспечить дос-
таточное место для каждого индивидуального стека потока, но и достаточно маленькой,
чтобы стеки некоторых потоков не попадали в область глобальных данных mysqld. К
сожалению, как мы экспериментально установили, реализация вызова mmp () в Linux ус-
пешно снимет отображение с уже отображенной области, если вы запросите его отобра-
зить адрес, который уже занят, обнуляя данные целой страницы вместо того, чтобы вер-
нуть ошибку. Поэтому безопасность mysqld и любых других многопоточных при-
ложений зависит от "джентльменского" поведения кода, порождающего потоки.
Пользователь должен произвести замеры, чтобы убедиться, что количество работающих
потоков в любой момент времени достаточно мало, и стек потоков остается вне глобаль-
ной кучи. Вы можете контролировать это для mysqld, устанавливая соответствующее
значение переменной max_connections.
Если вы собираете MySQL самостоятельно, вы можете применить исправления для
LinuxThreads с целью лучшего использования стека (см. раздел 2.6.1.3). Если вы не хо-
тите этого делать, то должны будете установить значение переменной max_connections
равным более 500. Оно может быть даже меньше, если у вас имеется большой буфер клю-
чей, большие таблицы куч или какие-то другие особенности, которые вынуждают mysqld
выделять много памяти, или если вы запускаете ядро 2.2 с соответсвующим исправлением.
2.6. Замечания по поводу конкретных операционных систем 175

Если вы используете наш бинарный дистрибутив или RPM-модуль версии 3.23.25 или
более поздней, можете устанавливать значение max_connections равным 1500, предпо-
лагая, что не будет больших буферов ключей или таблиц куч с большим объемом дан-
ных. Чем сильнее вы ограничиваете STACKSIZE в LinuxThreads, тем больше потоков
сможете создать. Мы рекомендуем выбирать значение между 128 Кбайт и 256 Кбайт.
Если вы используете множество параллельных соединений, то можете пострадать от
свойства ядра 2.2, которое пытается предотвратить атаки типа "fork bomb", наказывая
процессы, порождающие много своих клонов или дочерних процессов. Это ограничива-
ет возможности масштабирования MySQL при увеличении количества параллельных
клиентов. В однопроцессорных системах мы обнаружили, что это проявляется очень
медленным порождением потоков, и подключение к серверу может длиться очень долго
(вплоть до одной минуты), и так же долго длится отключение. В многопроцессорных
системах мы наблюдали постепенное снижение скорости выполнения запросов при уве-
личении количества клиентов. В процессе поиска решения проблемы мы получили ис-
правление от одного из наших пользователей, который использовал его во время прове-
дения множества исправлений в своей системе. Это исправление доступно по адресу
http://www.mysql.com/Downloads/Patches/linuxfork.patch. Мы провели интенсивное
тестирование упомянутого исправления, как на тестовых, так и на рабочих системах. Он
существенно увеличивает производительность MySQL, не вызывая никаких побочных
эффектов, и мы рекомендуем его тем нашим пользователям, которые эксплуатируют
сильно загруженные серверы на базе ядра 2.2.
Этот недостаток был исправлен в ядре 2.4, поэтому, если вы не удовлетворены суще-
ствующей производительностью своей системы, вместо исправления ядра 2.2 может
быть проще провести модернизацию ядра до версии 2.4. В SMP-системах модернизация
также приведет к повышению производительности симметричной многопроцессорной
обработки в дополнение к исправлению дефекта.
Мы протестировали MySQL с ядром версии 2.4, работающим на двухпроцессорной
машине, и обнаружили, что масштабирование MySQL стало значительно лучше. Не бы-
ло практически никакого замедления при выполнении запросов любого типа с ростом
числа клиентских подключений до 1000, и фактор масштабирования MySQL (вычисляе-
мый как отношение производительности при обслуживании максимальном числе клиен-
тов к производительности при обслуживании одного клиента) составил 180%. Тот же
результат мы получили и на четырехпроцессорной системе: практически никакого за-
медления при росте количества клиентов до 1000 и фактор масштабирования 300%. На
основании этих результатов, для сильно загруженных SMP-серверов, работающих на
базе ядре 2.2, мы определенно рекомендуем модернизацию ядра до версии 2.4.
Мы открыли, что важно запускать процесс mysqld на ядре 2.4 с максимально воз-
можным приоритетом для достижения наивысшей производительности. Это может быть
сделано добавлением команды renice -20 $$ в сценарий mysqld_safe. Наше тестирова-
ние на четырехпроцессорной системе показало, что повышение приоритета увеличивает
производительность на 60% при нагрузке в 400 клиентов.
В настоящее время мы пытаемся собрать больше информации о том, насколько хо-
рошо работает MySQL на четырех- и восьмипроцессорных системах. Если вы имеете
доступ к таким системам и выполняли на них тестирования производительности, пожа-
луйста, присылайте нам информацию о результатах по электронной почте на адрес
[email protected].
176 Глава 2. Установка MySQL

Если вы видите мертвый процесс mysqld в листинге команды ps, обычно это означа-
ет, что вы нашли ошибку в MySQL, или же у вас имеется поврежденная таблица. См.
раздел А.4.2.
Чтобы получить дамп памяти в Linux в случае зависания mysqld с сигналом
SIGSEGV, запустите mysqld с опцией — c o r e - f i l e . Обратите внимание на то, что,
возможно, вам придется увеличить допустимый размер файла дампа памяти, добавив
строку ulimit -с 1000000 в сценарий mysqld_safe или запустив mysqld_safe с опцией
--core-f ilesize=1000000. См. раздел 4.1.3.

2.6.1.5. Замечания по Linux x86


MySQL требует библиотеки l i b c версии 5.4.12 или более новой. Известно, что он ра-
ботает с l i b c 5.4.46. Библиотеки g l i b c 2.0.6 и последующих версий также должны рабо-
тать. Существовали некоторые проблемы с RPM-модулями g l i b c от Red Hat, поэтому,
если возникают проблемы, проверьте, нет ли каких-то обновлений, g l i b c 2.0.7-19 и
RPM-модули 2.0.7-29 работают нормально.
Если вы работаете с Red Hat 8.0 или новой библиотекой g l i b c 2.2.x, то можете столк-
нуться с ситуацией, когда mysqld зависает при вызове gethostbyaddr (). Это происходит
потому, что библиотека g l i b c для этого вызова требует размера стека в 128 Кбайт. Чтобы
исправить эту проблему, запускайте mysqld с опцией —thread-stack=192K. (До MySQL
4 соответствующая опция выглядела как -0 thread_stack=192K). Начиная с MySQL
4.0.10 и выше, размер стека по умолчанию увеличен до этого значения, поэтому вы не
должны столкнуться с этой проблемой в новых версиях.
Если вы используете дсс 3.0 и выше для компиляции MySQL, то должны установить
библиотеку Iibstdc++v3 до компиляции MySQL. Если этого не сделать, на этапе компо-
новки вы получите ошибку об отсутствующем символе cxa_pure_virtual.
В некоторых старых дистрибутивах Linux configure может генерировать следующие
сообщения об ошибках:
Syntax error in sched.h. Change _P to P in the
/usr/include/sched.h file.
See the Installation chapter in the Reference Manual.
Синтаксическая ошибка в sched.h. Измените _Р на P в файле
/usr/include/sched.h.
См. главу Installation (Установка) в справочном руководстве.
Просто сделайте то, что рекомендовано в этом сообщении. Добавьте дополнитель-
ный знак подчеркивания к имени макроса _Р, которое имеет только одно подчеркивание,
и попробуйте запустить configure снова.
Во время компиляции вы можете получить некоторые предупреждения. Перечислен-
ные ниже предупреждения можно проигнорировать:
mysqld.ее -о objs-thread/mysqld.o
mysqld.ee: In function 4 void init_signals()':
mysqld.cc:315: warning: assignment of negative value 4 - l ' to
4
long unsigned int'
mysqld.ee: In function 4 void * signal_hand(void * ) ' :
mysqld.cc:346: warning: assignment of negative value 4 - l ' to
N
long unsigned int'
2.6. Замечания по поводу конкретных операционных систем 177

Если mysqld сбрасывает дамп памяти при запуске, проблема может быть вызвана
старой библиотекой / l i b / l i v e . а. Попробуйте переименовать ее, затем удалите
sql/mysqld, заново выполните make i n s t a l l и попробуйте запустить mysqld снова. Об
этой проблеме также сообщалось для некоторых установок Slackware.
Если вы получаете следующие сообщения об ошибках во время компоновки mysqld,
это означает, что у вас не установлена правильно библиотека libg++. a:
/usr/lib/libc.a(putc.o): In function 4 _I0_putc':
putc.o (.text+OxO): multiple definition of v_IO_putc'
/usr/lib/libc.a (putc.o) : В функции y_IO_putc ':
putc.o(.text+OxO): множественное объявление y_IO_putc'
Вы можете исключить использование libg++.a, запустив configure таким образом:
shell> CXX=gcc ./configure
Если mysqld терпит крах немедленно, а у вас установлена система Red Hat 5.0 с вер-
сией glibc, предшествующей 2.0.7-5, убедитесь, что установлены все необходимые ис-
правления glibc. Много информации об этом можно найти в почтовых архивах MySQL,
доступных в по адресу http://lists.mysql.com/.
2.6.1.6. Замечания по Linux SPARC
В некоторых реализациях вызов readdir_r() неустойчив. Симптом заключается в
том, что команда SHOW DATABASES всегда возвращает пустой набор. Это может быть ис-
правлено удалением HAVE_READDIR_R из config.h после конфигурирования и до компи-
ляции.

2.6.1.7. Замечания по Linux Alpha


MySQL 3.23.12 - это первая версия MySQL, которая тестировалась на Linux-Alpha.
Если вы планируете использовать MySQL на Linux-Alpha, убедитесь, что у вас именно
эта версия или более новая.
Мы протестировали MySQL на Alpha с помощью наших наборов тестов функцио-
нальности и производительности и убедились в его нормальной работе.
В настоящее время мы собираем бинарные пакеты MySQL на SuSE Linux 7.0 for
АХР, ядро 2.4.4-SMP, с использованием компиляторов Compaq С (V6.2-505) и Compaq
C++ (V6.3-006) на машине Compaq DS20 с процессором Alpha EV6.
Упомянутые компиляторы доступны по адресу http://www.support.compaq.com/
alpha-tools/. За счет применения этих компиляторов вместо дес мы добились 9-14%
улучшения производительности MySQL.
Следует отметить, что до версий MySQL 3.23.52 и 4.0.2 мы оптимизировали бинар-
ный код только для текущего процессора (используя опцию компилятора -fast). Это
означает, что для более старых версий вы можете использовать наши бинарные дистри-
бутивы Alpha, но только если у вас процессор Alpha EV6.
Для всех последующих выпусков мы добавили флаг -arch generic к нашим опциям
компилятора, который гарантирует, что бинарный код будет работать на всех процессо-
рах Alpha. Кроме того, мы все компонуем статически, во избежание проблем с библио-
теками. Команда configure выглядит примерно так:
СС=ссс CFLAGS="-fast -arch generic" CXX=cxx \
CXXFLAGS="-fast -arch generic -noexceptions - n o r t t i " \
./configure —prefix=/usr/local/mysql —disable-shared \
178 Глава 2. Установка MySQL

—with-extra-charsets=complex —enable-thread-safe-client \
—with-mysqld-ldflags=-non_shared —with-client-ldflags=-non_shared
Если вы хотите использовать egcs, то подойдет следующая строка configure:
CFLAGS="-O3 -fomit-frame-pointer" CXX=gcc \
CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors \
-fno-exceptions - f n o - r t t i " \
./configure —prefix=/usr/local/mysql —disable-shared
Ниже перечислены некоторые известные проблемы при работе MySQL на Linux-
Alpha:
• Отладка многопоточных приложений, подобных MySQL, в gdb 4.18 не работает.
Используйте вместо этого gdb 5.1.
• Если вы пытаетесь компоновать mysqld статически при использовании дсс, то ре-
зультирующий код приводит к выгрузке дампа памяти немедленно при старте.
Другими словами, не используйте — with-mysqld-ldf lags=-all-static с дсс.

2.6.1.8. Заметки о Linux PowerPC


MySQL должен работать на MkLinux с новейшим пакетом glibc (тестировался с
glibc 2.0.7).

2.6.1.9. Замечания по Linux MIPS


Чтобы обеспечить работу MySQL на Qube2 (Linux MIPS), понадобится новейшая
версия библиотек glibc. Известно, что работает glibc 2.0.7-29C2. Вы должны использо-
вать компилятор egcs C++ (egcs-1.0.2-9, gcc 2.95.2 или более новые).

2.6.1.10. Замечания по Linux IA-64


Чтобы скомпилировать MySQL на Linux IA-64, мы используем следующую строку
для configure:
CC=gcc \
CFLAGS="-O3 -fno-omit-frame-pointer" \
CXX=gcc \
CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors \
-fno-exceptions - f n o - r t t i " \
./configure —prefix=/usr/local/mysql \
"--with-comment=Official MySQL binary" \
—with-extra-charsets=complex
Ha IA-64 клиентские программы используют разделяемые библиотеки. Это озна-
чает, что если вы устанавливаете бинарный дистрибутив в место, отличное от
/usr/local/mysql, то должны добавить путь к каталогу, где находится libmysqlclient.so,
либо в /etc/Id.so.conf, либо в переменную окружения LD_LIBRARY_PATH. См. раздел
А.3.1.

2.6.2. Замечания по Max OS X


В среде Max OS X программа t a r не обрабатывает длинных имен файлов. Если вам
нужно распаковать дистрибутив в формате . t a r .gz, используйте gnutar.
2.6. Замечания по поводу конкретных операционных систем 179

2.6.2.1. Mac OS X 10.x (Darwin)


MySQL должен без проблем работать под управлением Mac OS X 10.x (Darwin).
Наш бинарный дистрибутив для Mac OS X компилируется в Darwin 6.3 со следую-
щей строкой configure:
CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc \
CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors \
-fno-exceptions -fno-rtti" \
./configure —prefix=/usr/local/mysql \
—with-extra-charsets=complex —enable-thread-safe-client \
—enable-local-infile —disable-shared
См. раздел 2.2.З.

2.6.2.2. Mac OS X Server 1.2 (Rhapsody)


В текущей версии Mac OS X Server перед компиляцией MySQL никаких изменений в
операционной системе проводить не требуется. Компиляция для серверной платформы
точно такая же, как и для клиентской версии Mac OS X. (Однако следует отметить, что
MySQL поставляется заранее установленным в Mac OS X, поэтому нет необходимости
собирать его самостоятельно.)
В более старых версиях (Mac OS X Server 1.2, известная как Rhapsody), прежде чем
конфигурировать MySQL, вы должны установить пакет pthread.
См. раздел 2.2.3.

2.6.3. Замечания по Solaris


В среде Solaris вы можете столкнуться с проблемой еще до того, как получите распа-
кованный дистрибутив MySQL! Программа t a r , поставляемая с Solaris, не поддерживает
длинных имен файлов. Заранее скомпилированная копия для Solaris доступна по адресу
http://dev.mysql.com/downloads/os-solaris.html.
Встроенная поддержка потоков от Sun работает только под управлением Solaris 2.5 и
выше. Для версии до 2.4 включительно MySQL автоматически использует MIT-pthreads
(см. раздел 2.3.5).
Если вы получаете следующую ошибку во время работы configure, это означает, что
у вас что-то не так с установкой компилятора:
checking for restartable system c a l l s . . . configure: error can not
run t e s t programs while cross compiling
проверка перезапускаемых системных вызовов... configure: ошибка невозможности
запуска тестовых программ во время кросс-компиляции
В этом случае потребуется модернизировать компилятор до более свежей версии.
Можно также попытаться решить эту проблему, вставив следующую строку в файл
config.cache:
ac_cv_sys_restartable_syscalls=${ac_cv_sys_restartable_syscalls='nol}
Если вы работаете в Solaris на SPARC, рекомендуется пользоваться компилятором
дес 2.95.2 или 3.2. Его можно найти по адресу h t t p : / / g c c . g n u . o r g / . Имейте в виду, что
eges 1.1.1 и дес 2.8.1 на SPARC работают ненадежно!
При использовании компилятора дес 2.95.2 рекомендуемая строка configure выгля-
дит следующим образом:
180 Глава 2. Установка MySQL

COgcc CFLAGS="-03" \
CXX=gcc CXXFLAGS="-03 - f e l i d e - c o n s t r u c t o r s -fno-exceptions - f n o - r t t i " \
./configure —prefix=/usr/local/mysql —with-low-memory \
—enable-assembler
Если вы работаете в системе UltraSPARC, то можете получить производительность
на 4% выше, добавив -mcpu=v8 -Wa,-xarch=v8plusa к переменным окружения CFLAGS и
CXXFLAGS.
В случае использования компилятора Sun Forte 5.0 (или более новой версии)
configure можно запускать так:
СС=сс CFLAGS="-Xa -fast -native -xstrconst -mt" \
CXX=CC CXXFLAGS="-noex -mt11 \
./configure —prefix=/usr/local/mysql —enable-assembler
Для получения 64-разрядного бинарного кода с помощью компилятора Sun Forte при-
меняйте следующие опции конфигурации:
СС=сс CFLAGS="-Xa -fast -native -xstrconst -mt -xarch=v9" \
CXX=CC CXXFLAGS="-noex -mt -xarch=v9" ASFLAGS=fl-xarch=v9lf \
./configure —prefix=/usr/local/mysql —enable-assembler
Чтобы получить 64-разрядный бинарный код Solaris с помощью компилятора дсс,
добавьте -тб4 к CFLAGS и CXXFLAGS и удалите —enable-assembler из строки configure.
Это работает только с MySQL 4.0 и выше. MySQL 3.23 не содержит требуемых модифи-
каций для поддержки этого.
Во время тестирования производительности MySQL мы получили прирост скорости
в 4% на UltraSPARC с компилятором Forte 5.0 в 32-разрядном режиме по сравнению с
дсс 3.2 с флагом -mcpu.
Если вы собираете 64-разрядный бинарный код mysqld, то обнаружите, что он на 4%
медленнее, чем 32-разрядный вариант, но поддерживает больше потоков и памяти.
Если вы получите проблемы с fdatasync или sched_yield, можете исправить это, до-
бавив LIBS=-lrt в строку configure.
Для компиляторов, предшествующих Workshop 5.3, возможно, потребуется отредак-
тировать строку configure. Измените строку:
#if ! defined (_STDC__) | | _STDC_ != 1
на
#if !defined(__STDC_J
Если вы включите STDC с помощью опции -Хс, компилятор Sun не сможет вклю-
чить файл pthread.h. Это ошибка Sun (поврежден компилятор или заголовочный файл).
Если mysqld во время запуска выдает приведенное ниже сообщение об ошибке, зна-
чит, вы попытались скомпилировать MySQL компилятором Sun без опции -mt:
libc internal error: _rmutex_unlock: rmutex not held
Добавьте -mt к CFLAGS и CXXFLAGS и перекомпилируйте.
Если вы используете SFW-версию дсс (которая поставляется вместе с Solaris 8), то
должны добавить /opt/swf/lib к переменной окружения LD_LIBRARY_PATH до запуска
configure.
2.6. Замечания по поводу конкретных операционных систем 181

При использовании дсс, полученного от sunfreeware.com, можно столкнуться со


множеством проблем. Чтобы избежать их, необходимо перекомпилировать дсс и GNU
b i n u t i l s на той машине, на которой вы собираетесь их запускать.
Если вы получаете следующую ошибку при компиляции MySQL с помощью дсс, это
означает, что дсс не сконфигурирован для вашей версии Solaris:
s h e l l > gcc -03 -g -02 -DDBUGJDFF -о thr__alarm . . .
x
./thr_alarm.c: In function signal_hand':
4
./thr_alarm.c:556: too many arguments to function sigwait'
Самое правильно, что можно сделать в этом случае, - это получить более новую вер-
сию дсс и перекомпилировать ее вашим текущим компилятором дсс. По крайней мере,
для Solaris 2.5, почти все старые бинарные версии дсс имеют устаревшие файлы заго-
ловков, которые разрушают все программы, использующие потоки, а может быть, и не
только потоки!
Solaris не поставляет статических версий системных библиотек ( l i b p t h r e a d s и
l i b d l ) , поэтому вы не сможете скомпилировать MySQL с — s t a t i c . Если попытаетесь
это сделать, получите одну их следующих ошибок:
Id: f a t a l : library - l d l : not found
undefined reference to 'dlopen'
cannot find - l r t
А если вы скомпонуете собственные клиентские программы, то при работе их может
быть выдана такая ошибка:
ld.so.l: fatal: libmysqlclient.so.#:
open f a i l e d : No such f i l e or d i r e c t o r y
Этой проблемы можно избежать одним из следующих способов:
• Выполняйте компоновку клиентов с флагом -Wl,r/полный/путь/к/libmysqlclient.so
вместо -Ълуть.
• Скопируйте l i b m y s q c l i e n t . s o в / u s r / l i b .
• Добавьте путь к каталогу, где находится l i b m y s q c l i e n t . s o , к переменной окру-
жения LD_RUN_PATH, прежде чем запускать клиентские программы.
Если у вас возникают проблемы с configure при компоновке с - l z , когда нет уста-
новленной библиотеки z l i b , существуют два выбора:
• Если вы хотите использовать сжатый коммуникационный протокол, вам нужно
получить z l i b из f t p . gnu. org и установить ее.
• Запустить configure с опцией —with-named-z-libs=no во время сборки MySQL.
Если вы используете дсс и сталкиваетесь с проблемами при загрузке в MySQL опре-
деляемых пользователем функций (UDF), попробуйте добавить - l g c c в строку компо-
новки для UDF.
Если вы хотите, чтобы MySQL запускался автоматически, можете скопировать
support-files/mysql. server в / e t c / i n i t . d и создать символическую ссылку на него с
именем /etc/гсЗ.d/S99mysql.server.
Если случается так, что слишком много процессов пытаются быстро подключиться к
mysqld, вы увидите в журнале ошибок MySQL следующую строку:
Error in accept: Protocol error
182 Глава 2. Установка MySQL

Для того чтобы обойти это, можете попробовать запустить сервер с опцией
—back_log=50. (До версии MySQL 4.0 используйте -0 back_log=50.)
Solaris не поддерживает файлы образов памяти для приложений с вызовами
setuid (), поэтому вы не сможете получить этот файл от raysqld, если указываете опцию
—user.

2.6.3.1. Замечания по Solaris 2.7/2.8


Обычно вы можете использовать бинарные программы для Solaris 2.6 в Solaris 2.7 и
2.8. Большинство продуктов Solars 2.6 также используются в Solaris 2.7 и 2.8.
MySQL 3.23.4 и выше должен быть готов автоматически определять новые версии
Solaris и включать обходные пути для решения описанных ниже проблем.
Solaris 2.7 и 2.8 имеют некоторые ошибки во включаемых файлах. Во время исполь-
зования дсс может выдаваться следующая ошибка:
/usr/include/widec.h:42: warning: Ngetwc' redefined
/usr/include/wchar.h:326: warning: this is the location of the previous
definition
/usr/include/widee.h:42: предупреждение: *getwc' переопределена
/usr/include/wchar.h:326: предупреждение: это расположение предыдущего
определения
Если такое случится, исправить ошибку можно, скопировав /usr/include/widec.h в
.. /lib/gcclib/os/gcc-version/include и изменив строку 41 с
#if !defined(lint) && !defined( lint)
на
#if Idefined(lint) && !defined( lint) && !defined(getwc)
В качестве альтернативы, можно отредактировать /usr/include/widec.h непосред-
ственно. В любом случае, после этого исправления необходимо удалить config. cache и
запустить configure снова.
Причина возникновения следующих ошибок при запуске make состоит в том, что
configure не находит файл curses.h (возможно, из-за ошибки в /usr/include/widec.h):
In file included from mysql.ee:50:
/usr/include/term.h:1060: syntax error before 4,'
/usr/include/term.h:1081: syntax error before ;'
Для решения этой проблемы можно предпринять следующие действия:
• И з м е н и т ь В . / c o n f i g u r e CFLAGS=-DHAVE_CURSES_H CXXFLAGS=-DHAVE_CURSES_H.
• Отредактировать /usr/include/widec.h, как показано выше, и перезапустить
configure.
• Удалить строку Idefine HAVEJTERM из файла config.h, после чего запустить make
снова.
Если ваш компоновщик не находит -lz при выполнении сборки ваших клиентских
программ, возможно, проблема заключается в том, что файл libz.so установлен в ката-
логе /usr/local/lib. Решить ее можно одним из следующих способов:
• Добавить /usr/local/lib в LD_LIBRARY_PATH.
• Добавить ссылку на l i b z . so из /lib.
2.6. Замечания по поводу конкретных операционных систем 183

• Если вы работаете в Solaris 8, можете установить необязательную утилиту zlib из


дистрибутива Solaris 8 на компакт-диске.
• Запустить configure с опцией —with-named-z-libs=no при сборке MySQL.

2.6.3.2. Замечания по Solaris х8б


В Solaris 8 для х86 сервер mysqld сбрасывает дамп памяти, если с помощью програм-
мы s t r i p удалить из бинарного кода отладочную информацию.
Если вы используете дсс или egcs в Solaris x86 и сталкиваетесь с выдачей дампа па-
мяти во время загрузки, выдайте следующую команду configure:
CC=gcc CFLAGS="-O3 -fomit-frame-pointer -DHAVE_CURSES_H" \
CXX=gcc \
CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors \
-fno-exceptions -fno-rtti -DHAVE_CURSES_H" \
./configure —prefix=/usr/local/mysql
Это позволит избежать проблем, связанных с библиотекой libstdc++ и исключения-
ми C++.
Если это не поможет, скомпилируйте отладочную версию и запустите ее с файлом
трассировки или в отладчике gdb.

2.6.4. Замечания по BSD


В этом разделе представлена информация об использовании MySQL на различных
вариациях BSD Unix.

2.6.4.1. Замечания по FreeBSD


Для функционирования MySQL рекомендуется FreeBSD версии 4.0 и старше, по-
скольку в них гораздо лучше интегрирован пакет поддержки потоков. Чтобы получить
защищенную и стабильную систему, вы должны использовать только те ядра FreeBSD,
которые помечены как -RELEASE.
Наиболее простой (и предпочтительный) способ установки MySQL предполагает ис-
пользование пакетов mysql-server и mysql-clients, которые доступны на сайте
http://www.freebsd.org/. Применение упомянутых пакетов обеспечивает следующие
преимущества:
• Работоспособный MySQL с включенной оптимизацией, о котором точно извест-
но, что он будет работать под управлением вашей версии FreeBSD.
• Автоматическое конфигурирование и сборка.
• Сценарии запуска, установленные в каталоге /usr/local/etc/rc. d.
• Возможность получить информацию об установленных файлах с помощью ко-
манды pkg_infо -L.
• Возможность удаления установки MySQL с машины с помощью команды
pkg_delete.
Рекомендуется использовать MIT-pthreads в FreeBSD 2.x и встроенную поддержку
потоков в версии FreeBSD 3 и выше. Вообще говоря, существует возможность работать
со встроенными потоками в поздних версиях 2.2.x, однако вы можете столкнуться с про-
блемами при останове mysqld.
184 Глава 2. Установка MySQL

К сожалению, некоторые вызовы функций в FreeBSD пока еще не вполне безопасны


в отношении потоков. В первую очередь следует упомянуть функцию gethostbynameO,
которую использует MySQL для преобразования имен хостов в IP-адреса. При некото-
рых обстоятельствах процесс mysqld неожиданно загружает процессор на 100% и пере-
стает реагировать на запросы. Если вы столкнетесь с этой проблемой, попробуйте запус-
тить mysqld с опцией —skip-name-resolve.
В качестве альтернативы, можете скомпоновать MySQL в FreeBSD с библиотекой
LinuxThreads, которая решает часть проблем, существующих в реализации поддержки
потоков FreeBSD. Очень хорошее сравнение LinuxThreads со встроенными потоками
приведено в статье Джереми Заводны (Jeremy Zawodny) "FreeBSD or Linux for your
MySQL Server?" ("FreeBSD или Linux для вашего сервера MySQL?"), оригинал которой
доступен по адресу h t t p : //Jeremy, zawodny.com/blog/archives/000697 .html.
Известная проблема при использовании LinuxThreads в среде FreeBSD состоит в том,
что значение waittimeout не принимается во внимание (вероятно, из-за сложностей с
обработкой сигналов FreeBSD/LinuxThreads). Ожидается, что это будет исправлено в
FreeBSD 5.0. Симптомы проявляются в том, что постоянные подключения могут зави-
сать на длительное время, не давая возможности их закрыть.
Процесс сборки MySQL для своей работы требует GNU make (gmake). Если GNU make
отсутствует, необходимо его установить до начала компиляции MySQL.
Ниже представлен рекомендуемый способ компиляции и установки MySQL в среде
FreeBSD с помощью дсс (версии 2.95.2 и выше):
СС=дсс CFLAGS="-02 -fno-strength-reduce" \
СХХ=дсс CXXFLAGS="-02 -fno-rtti -fno-exceptions \
-felide-constructors -fno-strength-reduce" \
./configure —prefix=/usr/local/mysql —enable-assembler
gmake
gmake install
cd /usr/local/mysql
bin/mysql_install_db —user=mysql
bin/mysqld_safe &
Если вы решите, что configure будет использовать MIT-pthreads, прочтите раздел
2.3.5.
Если make i n s t a l l выдаст сообщение об ошибке, связанной с невозможности найти
/usr/include/pthreads, значит, configure не может обнаружить MIT-pthreads. Для ис-
правления этой проблемы удалите config. cache, после чего перезапустите configure с
опцией —with-mit-pthreads.
Убедитесь в том, что преобразование имен работает правильно. Иначе вы можете
столкнуться с задержками или отказами при попытках подключения к mysqld. Также
убедитесь в том, что позиция localhost корректно описана в файле /etc/hosts. Этот
файл должен начинаться со строки, подобной приведенной ниже:
127.0.0.1 localhost localhost.ваш.домен
Известно, что у FreeBSD установлен очень низкий лимит на число открытых файлов.
См. раздел А.2.17. Запускайте сервер с опцией --open-files-limit для mysqld_safe, или
увеличьте ограничения для пользователя mysqld в /etc/login.conf и пересоберите его с
capjnkdb /etc/login.conf. Также убедитесь, что вы установили соответствующий
2.6. Замечания по поводу конкретных операционных систем 185

класс для пользователя в файле паролей, если вы не применяете соглашения по умолча-


нию (используйте chpass имя-пользователя-mysqld). См. раздел 4.1.3.
Если объем памяти, который находится в вашем распоряжении, достаточно велик,
стоит рассмотреть возможность перекомпиляции ядра, чтобы позволить MySQL исполь-
зовать свыше 512 Мбайт памяти. Для получения более подробной информации взгляни-
те на опцию MAXDSIZ в файле конфигурации LINT.
В случае возникновения проблем с текущей датой в MySQL может помочь установка
переменной TZ. См. приложение Б.

2.6.4.2. Замечания по NetBSD


Для выполнения компиляции под NetBSD необходима GNU make. В противном слу-
чае процесс сборки прервется по ошибке, когда make попытается запустить l i n t для
файлов C++.

2.6.4.3. Замечания по OpenBSD 2.5


В среде OpenBSD версии 2.5 можно скомпилировать MySQL со встроенными пото-
ками, если использовать следующие опции:
CFLAGS=-pthread CXXFLAGS=-pthread ./configure —with-mit-threads=no
2.6.4.4. Замечания по OpenBSD 2.8
Наши пользователи сообщили, что OpenBSD 2.8 содержит ошибку, связанную с по-
токами, которая приводит к проблемам в MySQL. Разработчики OpenBSD исправили ее,
но по состоянию на 25 января 2001 года это исправление доступно только в ветви
"-current". Симптомами этой ошибки являются замедленная реакция, высокая загрузка
процессора и крах системы.
Если вы получаете сообщение об ошибке вроде "Error in accept:: Bad f i l e
descriptor" ("Ошибка при чтении:: Неверный дескриптор файла") или ошибку 9 при
попытке открыть таблицы или каталоги, то возможно, причина в том, что для MySQL
выделено недостаточное количество дескрипторов файлов.
В этом случае попробуйте запустить mysql_safe от имени root со следующими клю-
чами:
roysqld_safe —user=mysql —open-files-limit=2048 &
2.6.4.5. Замечания по BSD/OS версии 2.x
Если во время компиляции MySQL вы получили приведенное ниже сообщение об
ошибкеj это значит, что ваш лимит виртуальной памяти ulimit слишком мал:
item_func.h: In method
v
Item_func_ge: :Item_func_ge (const Item_func__ge &) ' :
item_func.h:28: virtual memory exhausted
make[2]: *** [item_func.o] Error 1
Попытайтесь установить ulimit -v 80000 и запустите make снова. Если вы исполь-
зуете командную оболочку bash и это не срабатывает, попробуйте перейти на оболочку
csh или sh. Некоторые пользователи BSDI сообщали о проблемах с bash и ulimit.
Если вы применяете дсс, возможно, вам стоит указать флаг —with-low-memory для
configure, чтобы получить возможность скомпилировать sql_yacc.cc.
Если у вас возникли проблемы с текущей датой в MySQL, возможно, поможет уста-
новка переменной TZ. См. приложение Б.
186 Глава 2. Установка MySQL

2.6.4.6. Замечания по BSD/OS версии 3.x


Модернизируйте систему до версии BSD/OS 3.1. Если это невозможно, примените
исправление BSDIpatch M300-038.
При конфигурировании MySQL воспользуйтесь следующей командой:
env CXX=shlicc++ CC=shlicc2 \
./configure \
—prefix=/usr/local/mysql \
—localstatedir=/var/mysql \
—without-perl \
—with-unix-socket-path=/var/mysql/mysql.sock
Приведенный ниже вариант тоже работает:
env COgcc CXX=gcc CXXFLAGS=-O3 \
./configure \
—prefix=/usr/local/mysql \
—with-unix-socket-path=/var/mysql/mysql.sock
Если хотите, можете изменить местоположение каталога, или же использовать ме-
стоположение, принятое по умолчанию, не указав никакого.
Если возникают проблемы с производительностью при большой нагрузке, попробуй-
те применить опцию —skip-thread-priority для mysqld. Это позволяет выполнять все
потоки с одинаковыми приоритетами. В BSDI 3.1 это обеспечит более высокую произ-
водительность, по крайней мере, до тех пор, пока BSDI не исправит свой диспетчер по-
токов.
Если во время компиляции вы получаете сообщение об ошибке наподобие "virtual
memory exhausted" ("виртуальная память исчерпана"), нужно попробовать установить
ulimit -v 80000 и запустить make снова. Если вы используете командную оболочку
bash и это не срабатывает, попробуйте перейти на csh или sh. Некоторые пользователи
BSDI сообщали о проблемах с bash и ulimit.

2.6.4.7. Замечания по BSD/OS версии 4.x


BSDI 4.x имеет те же ошибки, связанные с потоками. Если вы хотите использовать
MySQL в этой системе, вы должны применить все исправления, касающиеся потоков.
Как минимум, потребуется применить М400-023.
В некоторых системах BSDI 4.x вы можете столкнуться с проблемами, имеющими
отношение к разделяемым библиотекам. Симптомом является невозможность запустить
клиентскую программу, например mysqladmin. В этом случае нужно переконфигуриро-
вать сборку, указав configure опцию —disable-shared.
Некоторые наши потребители сталкивались с проблемой в BSDI 4.0.1, которая выра-
жалась в том, что mysqld в течение длительного времени не мог открыть таблицы. Это
связано с тем, что некоторые библиотечные/системные ошибки заставляют mysqld сме-
нять текущий каталог, хотя его об этом не просят.
Для того чтобы исправить это, необходимо либо модернизировать MySQL как мини-
мум, до версии 3.23.34, либо после запуска configure удалить #define HAVE_REALPATH из
config.h перед запуском make.
Заметьте, это означает, что в BSDI вы не сможете создавать символические ссылки,
чтобы связать один каталог данных с другим или таблицу с другой базой данных (созда-
ние символических ссылок на другой диск работает нормально).
2.6. Замечания по поводу конкретных операционных систем 187

2.6.5. Замечания по другим системам Unix


2.6.5.1. Замечания по HP-UX версии 10.20
Существует несколько незначительных проблем при компиляции MySQL в среде HP-
UX. Мы советуем использовать дсс вместо встроенного компилятора HP-UX, так как
дсс генерирует более качественный код. В HP-UX лучше всего применять дсс 2.95. Не
используйте флаги включения высокой оптимизации (типа -Об), поскольку они могут
оказаться небезопасными для HP-UX.
Следующая строка configure должна работать с дсс 2.95:
CFLAGS="-I/opt/dce/include -fpic" \
CXXFLAGS="-I/opt/dce/include -felide-constructors -fno-exceptions \
-fno-rtti" \
CXX=gcc \
./configure —with-pthread \
—with-named-thread-libs='-Idee' \
—prefix=/usr/local/mysql —disable-shared
Приведенная ниже строка configure должна работать с дсс 3.1:
CFLAGS="-DHPUX -I/opt/dce/include -03 -fPIC" CXX=gcc \
CXXFLAGS="-DHPUX -I/opt/dce/include -felide-constructors \
-fno-exceptions -fno-rtti -03 -fPIC" \
./configure —prefix=/usr/local/mysql \
—with-extra-charsets=complex —enable-thread-safe-client \
—enable-local-infile —with-pthread \
—with-named-thread-libs=-ldce —with-lib-ccflags=-fPIC
—disable-shared

2.6.5.2. Замечания по HP-UX версии 11.x


Для работы в среде HP-UX 11.x мы советуем выбирать MySQL 3.23.15 или более
поздние версии.
Из-за некоторых критических ошибок в стандартных библиотеках HP-UX вы должны
применить следующие исправления, прежде чем можно будет успешно запускать
MySQL под управлением HP-UX 11.x:
PHKL_22840 Streams cumulative
PHNE_22397 ARPA cumulative
Это решает проблему возврата EWOULDBLOCK из recv() и EBADF из accept () в много-
поточных приложениях.
Если вы используете дсс 2.95.1 в системе HP-UX 11.x, в которой не применялись ис-
правления, то получите сообщение об ошибке вида:
In f i l e included from /usr/include/unistd.h:11,
from ../include/global.h:125,
from mysql joriv.h:15,
from item.ee:19:
/usr/include/sys/unistd.h:184: declaration of С function . . .
/usr/include/sys/pthread.h:440: previous declaration . . .
In file included from item.h:306,
from mysql_jpriv.h: 158,
from item.ee:19:
188 Глава 2. Установка MySQL

Проблема состоит в том, что HP-UX не определяет однозначно pthreads_atfork().


Существуют конфликтующие между собой прототипы в /usr/include/sys/unistd.h:184
и /usr/include/sys/pthread.h:440.
Одним из решений может быть копирование / u s r / i n c l u d e / s y s / u n i s t d . h в
mysql/include и редактирование unistd.h для приведения в соответствие с объявлением
в pthreads. h. Найдите строку:
extern i n t pthread_atfork(void (*prepare) ( ) , void ( * p a r e n t ) ( ) , void (*child)());

Исправьте ее следующим образом:


extern int pthread_atfork(void (^prepare)(void), void (*parent)(void),
void (*child)(void));
После внесения этого изменения следующая строка configure должна работать нор-
мально:
CFLAGS="-fomit-frame-pointer -03 -fpic" CXX=gcc \
CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti -03" \
./configure —prefix=/usr/local/mysql —disable-shared
Если вы имеете дело с MySQL 4.0.5 и компилятором HP-UX, можете воспользоваться
следующей командой:
СС=сс СХХ=аСС CFLAGS=+DD64 CXXFLAGS=+DD64 ./configure \
—with-extra-character-set=complex
Ошибки приведенного ниже типа можно игнорировать:
ч
аСС: warning 901: unknown o p t i o n : - 3 ' : use +help for o n l i n e
documentation
Если configure выдаст следующую ошибку, проверьте, не находится ли путь к ком-
пилятору K&R перед путем к компиляторам HP-UX С и C++:
checking for cc option to accept ANSI С . . . по
configure: e r r o r : MySQL requires an ANSI С compiler (and a C++ compiler).
Try gcc. See the I n s t a l l a t i o n chapter in the Reference Manual.
Другая причина невозможности компиляции может заключаться в том, что вы не оп-
ределили флаг +DD64, как было указано выше.
Можно воспользоваться бинарным дистрибутивом MySQL для HP-UX 10.20 на HP-
UX 11. У нас есть сообщения от ряда пользователей, у которых этот дистрибутив хоро-
шо работает под управлением HP-UX 11. В случае возникновения каких-либо проблем
проверьте уровень исправлений (patch level) своей системы HP-UX.

2.6.5.3. Замечания по IBM-AIX


Автоматическое обнаружение компилятора х1С пропущено в Autoconf, поэтому пе-
ред запуском configure необходимо установить множество переменных. В следующем
примере демонстрируется использование компилятора IBM:
export CC="xlc_r -ma -03 - q s t r i c t -qoptimize=3 -qmaxmem=8192 "
export CXX="xlC_r -ma -03 - q s t r i c t -qoptimize=3 -qmaxmem=8192"
export CFLAGS="-I /usr/local/include"
export LDFLAGS="-L /usr/local/lib"
export CPPFLAGS=$CFLAGS
export CXXFLAGS=$CFLAGS
2.6. Замечания по поводу конкретных операционных систем 189

./configure —prefix=/usr/local \
—localstatedir=/var/mysql \
—sysconfdir=/etc/mysql \
—sbindir='/usr/local/bin' \
—libexecdir='/usr/local/bin 1 \
—enable-thread-safe-client \
—enable-large-files
Перечисленные опции используются для компиляции дистрибутива MySQL, который
можно найти по адресу http://www-frec.bull.com/.
Если в предыдущей строке configure вы замените -03 на -02, то должны будете так-
же удалить опцию - q s t r i c t . Это ограничение компилятора С от IBM.
Если вы применяете дсс или egcs для компиляции MySQL, то должны использовать
флаг -fno-exceptions, потому что поддержка исключений у gcc/egcs небезопасна в от-
ношении потоков. (Проверено для egcs 1.1.) Существуют также некоторые проблемы с
ассемблером IBM, из-за которых он генерирует неудачный код при работе с дсс. Мы
советуем использовать следующую строку configure с egcs и дсс 2.95 на AIX:
СС="дсс -pipe -mcpu=power -Wa,-many" \
СХХ="дсс -pipe -mcpu=power -Wa,-many" \
CXXFLAGS="-felide-constructors -fno-exceptions - f n o - r t t i " \
. / c o n f i g u r e — p r e f i x = / u s r / l o c a l / m y s q l —with-low-memory
Опции -Wa и -many необходимы для успешной компиляции. В компании IBM знают
об этой проблеме, однако не торопятся ее исправлять, поскольку существует возмож-
ность ее обхода. Мы не знаем, нужна ли опция -fno-exceptions для дсс 2.95, но так как
код MySQL не использует исключений, и эта опция генерирует более быстрый код, ре-
комендуем всегда ее применять с компиляторами gcc/egcs.
Если вы столкнетесь с проблемами в ассемблерном коде, попробуйте изменить зна-
чение опции -гасри=ххх, чтобы оно соответствовало типу вашего процессора. Возможно,
понадобится указать power2, power или powerpc. Как альтернатива, может понадобиться
604 или 604е. Мы не на сто процентов уверены, но предполагаем, что значение power
должно оказаться безопасным в большинстве случаев, даже если у вас машина power2.
Если вы не знаете, какой тип процессора установлен, выполните команду uname -m.
Она выдаст строку, которая выглядит как 000514676700, в формате xxyyyyyymmss, где хх
и ss - всегда 00, уууууу - уникальный системный идентификатор и mm - идентификатор
процессора. Описание этих значений доступно по адресу:
http://publib.boulder.ibm.com/doc_link/en_US/a_doc_lib/cmds/aixcmds5/uname.htm
Это предоставит информацию о типе и модели машины, которую вы можете
использовать для определения типа центрального процессора.
Если возникают проблемы с сигналами (MySQL неожиданно зависает при высокой
нагрузке), возможно, они связаны с ошибками операционной системы, которые касают-
ся механизма потоков и сигналов. В этом случае вы можете указать MySQL не исполь-
зовать сигналы, сконфигурировав его следующим образом:
CFLAGS=-DDONT_USE_THR_ALARM CXX=gcc \
CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti \
-DDONT_USE_THR_ALARM" \
./configure —prefix=/usr/local/mysql —with-debug \
—with-low-memory
190 Глава 2. Установка MySQL

Это не повлияет на производительность MySQL, но приведет к побочному эффекту -


вы не сможете уничтожать спящие процессы клиентов, подключенных к серверу, с по-
мощью команды mysqladmin k i l l или mysqladmin shutdown. Клиент зависнет при выда-
че следующей команды.
В некоторых версиях AIX компоновка с libbind.a приводит к сбросу образа памяти
при вызове getservbyname (). Это ошибка AIX и о ней нужно сообщать в компанию
IBM.
С AIX 4.2.1 и дсс необходимо провести описанные далее изменения.
После конфигурирования отредактировать config.h и include/my_config.h, изменив
строку:
#define HAVE_SNPRINTF I
на:
#undef HAVE_SNPRINTF
В mysqld. ее добавить прототип initgroups ():
#ifdef _AIX41
extern "C" int initgroups(const char *,int);
tendif
Если процессу mysqld нужно выделить много памяти, недостаточно просто восполь-
зоваться ulimit -d unlimited. Вы можете также модифицировать mysqld_safe, добавив
строку вроде следующей:
export LDR_CNTRL='MAXDATA=0x80000000'
Дополнительную информацию по использованию большого объема памяти можно
найти по адресу http://publibl6.boulder.ibm.com/pseries/en_US/aixprggd/genprogc/
lrg_prg_support.htm.

2.6.5.4. Замечания по SunOS 4


В среде SunOS 4 для компиляции MySQL требуется поддержка потоков MIT-
pthreads. В свою очередь, это означает необходимость использования GNU make.
Некоторые системы SunOS 4 имеют проблемы с динамическими библиотеками и
libtool. Во избежание этих проблем следует пользоваться приведенной ниже строкой
configure:
./configure —disable-shared —with-mysqld-ldflags=-all-static
Во время компиляции readline вы можете получить предупреждения о двойных оп-
ределениях. Их можно проигнорировать.
При компиляции mysqld могут выдаваться предупреждения типа "implicit
declaration of function" ("неявное объявление функции"). Их также можно игнори-
ровать.

2.6.5.5. Замечания по Alpha-DEC-Unix (Tru64)


Если вы применяете eges 1.1.2 в среде Digital Unix, то должны модернизировать его
до дсс 2.95.2, поскольку с eges на машинах DEC связаны серьезные ошибки.
При компиляции многопоточных программ под Digital Unix документация рекоменду-
ет использовать опцию -pthread для компиляторов ее и есх, а также библиотек -lmach и
-lexc (в дополнение к -lpthread). Вы должны запускать configure примерно так:
2.6. Замечания по поводу конкретных операционных систем 191

СС="сс -pthread" CXX="cxx -pthread -0" \


./configure —with-named-thread-libs="-lpthread -lmach -lexc - l c "
Во время компиляции mysqld, возможно, будет выдано несколько предупреждений,
вроде таких:
mysqld.cc: In function void handle_connections()':
mysqld.ee:626: passing long unsigned int *' as argument 3 of
accept(int,sockadddr *, int * ) '
Вы можете спокойно проигнорировать эти предупреждения. Они появляются потому,
что configure может обнаруживать только ошибки, но не предупреждения.
Если вы запустите сервер непосредственно из командной строки, у вас могут возник-
нуть проблемы с его зависанием при выходе из системы. (При выходе из системы все
ваши процессы получают сигнал SIGHUP.) Если это так, попробуйте запустить сервер
следующим образом:
nohup mysqld [опции] &
nohup заставляет последующую команду игнорировать все сигналы SIGHUP, посту-
пающие от терминала. В качестве альтернативного способа запускайте сервер вызовом
сценария mysqld_safe, который запускает mysqld, используя nohup. См. раздел 4.1.3.
Если возникают проблемы при компиляции mysys/get_opt.c, просто удалите строку
#def ine _NO_PROTO в начале этого файла.
Для случая компилятора Compaq CC будет работать следующая строка configure:
СС="сс -pthread 11
CFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed all -arch host"
CXX="cxx -pthread"
CXXFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed a l l \
-arch host -noexceptions - n o r t t i "
export CC CFLAGS CXX CXXFLAGS
./configure \
—prefix=/usr/local/mysql \
—with-low-memory \
—enable-large-files \
—enable-shared=yes \
—with-named-thread-libs="-lpthread -lmach -lexc - l c "
gnumake
Если во время компоновки mysql возникли проблемы с компиляцией с разделяемыми
библиотеками, как показано выше, вы должны быть готовы обойти это, выполнив сле-
дующие команды:
cd mysql
/bin/sh ../libtool —mode=link exx -pthread -03 -DDBUG_OFF \
-04 -ansi_alias -ansi_args -fast -inline speed \
-speculate all \ -arch host -DUNDEF_HAVE_GETHOSTBYNAME_R \
-o mysql mysql.о readline.o sql_string.o completion_hash.o \
../readline/libreadline.a -leurses \
../libmysql/.libs/libmysqlclient.so -lm
cd ..
gnumake
gnumake install
scripts/mysql_install__db
192 Глава 2. Установка MySQL

2.6.5.6. Замечания по Alpha-DEC-OSF/1


Если вы столкнулись с проблемами компиляции и работаете с компиляторами DEC
СС и дсс, попробуйте запустить configure вот так:
СС=сс CFLAGS=-0 СХХ=дсс CXXFLAGS=-O3 \
./configure —prefix=/usr/local/mysql
Если проблемы связаны с файлом casm.h, можно создать файл-заглушку c_asm.h:
touch include/c_asm.h
CC=gcc CFLAGS=-I./include \
CXX=gcc CXXFLAGS=-O3 \
./configure —prefix=/usr/local/mysql
Имейте в виду, что следующие проблемы с программой Id можно решить, загрузив
последний набор исправлений от DEC (Compaq) из http://ftp.support.compaq.com/
public/unix/.
В операционной системе OSF/1 V4.0D с компилятором, именованным как " DEC С
V5.6-071 on Digital Unix V4.0 (Rev. 878)", последний странно себя ведет (неопределен-
ные символы asm), /bin/Id также выглядит поврежденным (проблемы с ошибками типа
exit undefined во время компоновки mysqld). В этой системе нам удалось скомпили-
ровать MySQL со следующей строкой configure, после замены /bin/Id версией из со-
става OSF 4.0C:
CC=gcc CXX=gcc CXXFLAGS=-03 ./configure --prefix=/usr/local/mysql
С компилятором от компании Digital "C++ V6.1-029" должно работать следующее:
СС=сс -pthread
CFLAGS=-04 -ansi_alias -ansi_args -fast -inline speed \
-speculate a l l -arch host
CXX=cxx -pthread
CXXFLAGS=-04 -ansi_alias -ansi_args -fast -inline speed \
-speculate a l l -arch host -noexceptions - n o r t t i
export CC CFLAGS CXX CXXFLAGS
./configure —prefix=/usr/mysql/mysql \
—with-mysqld-ldflags=-all-static —disable-shared \
—with-named-thread-libs="-lmach -lexc - l c "
В некоторых версиях OSF/1 повреждена функция alloca(). Это можно исправить,
удалив из config.h строку, которая определяет HAVE_ALLOCA.
Функция allocaO также может иметь неправильный прототип в /usr/include/
alloca.h. Предупреждение, которое появляется в результате этого, можно проигно-
рировать.
configure использует автоматически следующие библиотеки потоков:
—with-named-threadlibs="-lpthread -lmach -lexc - l c " .
При использовании дсс вы можете запустить configure так, как показано ниже:
CFLAGS=-D_PTHREAD_USE_D4 CXX=gcc CXXFLAGS=-03 . / c o n f i g u r e ...
Если возникают проблемы с сигналами (MySQL непредсказуемым образом сбоит при
высокой нагрузке), это может быть связано с ошибками операционной системы, которые
относятся к потокам и сигналам. В этом случае можно заставить MySQL не использо-
вать сигналы:
2.6. Замечания по поводу конкретных операционных систем 193

CFLAGS=-DDONT_USE_THR_ALARM \
CXXFLAGS=-DDONT_USE_THR_ALARM \
./configure ...
Последнее не повлияет на производительность MySQL, однако приведет к побочно-
му эффекту - вы не сможете уничтожать спящие процессы клиентов, подключенные к
серверу, с помощью команды mysqladmin k i l l или mysqladmin shutdown. Клиент завис-
нет при выдаче очередной команды.
При работе с компилятором дсс 2.95.2, возможно, вы получите следующее сообще-
ние об ошибке:
sql_acl.cc:1456: Internal compiler error in 4scan_region',
at except.c:2566
Please submit a full bug report.
Чтобы это исправить, потребуется перейти в каталог sql и вырезать, а затем вставить
последнюю строку вызова дсс, изменив -03 на -00 (или добавив -00 сразу после дсс,
если в строке вызова компилятора опции -0 отсутствуют). После того, как это будет сде-
лано, нужно вернуться в каталог верхнего уровня и запустить make снова.

2.6.5.7. Замечания по SGI Irix


Если вы работаете в среде Irix версии 6.5.3 или более новой, mysqld сможет порож-
дать потоки, только если вы запустите его от имени пользователя, имеющего привиле-
гии CAP_SCHED_MGT (например, root), или же предоставив серверу mysqld эту привиле-
гию с помощью следующей команды:
cheap "CAP_SCHED_MGT+epi" /opt/mysql/libexec/mysqld
Может потребоваться убрать определение некоторых символов после выполнения
configure и перед запуском компиляции.
В некоторых реализациях Irix функция a l l o c a ( ) сбоит. Если сервер mysqld зависает
при выполнении некоторых операторов SELECT, удалите из config.h строку, содержа-
щую HAVE_ALLOC и HAVE_ALLOC_H. Если не работает mysqladmin c r e a t e , удалите из
config.h строку, определяющую HAVE_READDIR_R. Также может понадобиться удалить
строку HAVE_TERM_H.
SGI рекомендует применять все исправления, которые можно найти на странице:
http://support.sgi.com/surfzone/patches/patchset/б.2_indigo.rps.html
Если во время компиляции mysqld. ее вы получаете что-то вроде:
" / u s r / i n c l u d e / c u r s e s . h " , l i n e 82: e r r o r ( 1 0 8 4 ) :
i n v a l i d combination of type
введите следующую команду, находясь в корневом каталоге дерева исходных текстов
MySQL:
extra/replace bool cursesjDool < /usr/include/curses.h > include/curses.h
make
Поступали также сообщения об ошибках, решение которых уже запланировано. Если
работает только один поток, производительность низка. Преодолеть это можно, запустив
еще одного клиента. Это приведет к возрастанию скорости от 2 до 10 раз для остальных.
Упомянутую проблему с потоками в Irix понять трудно; можете поэкспериментировать в
поисках лучшего решение, пока это не будет исправлено.
194 Глава 2. Установка MySQL

Если вы работаете с компилятором дсс, вызов configure должен выглядеть следую-


щим образом:
COgcc CXX=gcc CXXFLAGS=-O3 \
./configure --prefix=/usr/local/mysql --enable-thread-safe-client \
—with-named-thread-libs=-lpthread
В среде Irix 6.5 с родными компиляторами Irix С и C++ версии 1.3Л.2 работает такая
команда:
СС=сс СХХ=СС CFLAGS='-O3 -n32 -TARG:platform=IP22 -I/usr/local/include \
-L/usr/local/lib 1 CXXFLAGS='-03 -n32 -TARG:platform=IP22 \
-I/usr/local/include -L/usr/local/lib 1 \
./configure —prefix=/usr/local/mysql —with-innodb —with-berkeley-db \
—with-libwrap=/usr/local \
—with-named-curses-libs=/usr/local/lib/libncurses.a

2.6.5.8. Замечания по SCO


Текущий порт MySQL тестировался только в системах "sco3.2v5.0.5", "sco3.2v5.0.6"
и "sco3.2v5.0.7". Кроме того, существенный прогресс достигнут в версии "sco 3.2v4.2".
На данный момент для OpenServer мы рекомендуем пользоваться компилятором дсс
2.95.2. При этом должна получиться компиляция MySQL, если выполнено приведенное
ниже конфигурирование:
CC=gcc CXX=gcc ./configure ... [опции)
1. В среде OpenServer 5.0.x понадобится компилятор gcc 2.95.2pl или более новый, от
компании Skunware. Зайдите на http://www.sco.com/skunkware/ и выберите обзор
пакетов для OpenServer, или же выгрузите его через FTP с ftp2.caldera.com из ка-
талога pub/skunkware/osr5/devtools/gcc.
2. Вам понадобится порт GCC 2.5.x этого продукта и система разработки
(Development system). Они необходимы для данной версии SCO Unix. Недоста-
точно будет просто иметь GCC Dev system.
3. Вы должны будете получить пакет FSU Pthreads и установить его. Его можно найти
по адресу http://moss.esc.ncsu.edu/~mueller/ftp/pub/PART/pthreads.tar.gz.
4. FSU Pthreads можно скомпилировать в среде SCO UNIX 4.2 с tcpip, либо в
OpenServer 3.0, либо в Open Desktop 3.0 (OS 3.0 ODT 3.0) с установленным паке-
том SCO Development System, включающим в себя порт GCC 2.5.x. Для ODT или
OS 3.0 понадобится хороший порт GCC 2.5.x. Без этого может возникнуть множе-
ство проблем. Порт этого продукта требует наличия SCO Unix Development
System. Без этого пакета у вас не будет нужных библиотек и компоновщика.
5. Чтобы собрать FSU Pthreads на вашей системе, выполните следующие шаги:
1. Запустите ./configure, находясь в каталоге threads/src, и выберите опцию
SCO OpenServer. Эта команда скопирует Makefile.SC05 в Makefile.
2. Запустите make.
3. Чтобы установить в каталог по умолчанию /usr/include, войдите в систему
как root, перейдите в каталог threads/src и запустите make i n s t a l l .
6. Помните, что при сборке MySQL необходимо применять GNU make.
2.6. Замечания по поводу конкретных операционных систем 195

7. Если mysqld_safe не запускается от имени root, возможно, вы получите только


110 открытых файлов на процесс, mysqld запишет сообщение об этом в файл жур-
нала.
8. В системе SCO 3.2V5.0.5 вы должны использовать FSU Pthreads версии 3.5с или
выше. Также нужно использовать компилятор дсс 2.95.2 или более новый.
Следующая команда configure должна работать:
./configure —prefix=/usr/local/raysql —disable-shared
9. В системе SCO 3.2V4.2 необходимо использовать FSU Pthreads версии 3.5с или
выше. Работает следующая команда configure:
CFLAGS="-D_XOPEN_XPG4" CXX=gcc CXXFLAGS="-D_XOPEN_XPG4" \
./configure \
—prefix=/usr/local/mysql \
—with-named-thread-libs="-lgthreads -lsocket -lgen - I g t h r e a d s " \
—with-named-curses-libs="-lcurses"
Возможно, вы столкнетесь с некоторыми проблемами во включаемых файлах. В
этом случае можно загрузить новые специфичные для SCO включаемые файлы из
http://www.mysql.com/Downloads/SCO/SCO-3.2v4.2-includes.tar.gz. Эти файлы
потребуется распаковать в каталоге include дерева исходных текстов MySQL.
Ниже представлены замечания по разработке в SCO.
• MySQL должен автоматически обнаружить FSU Pthreads и скомпоновать mysqld с
-Igthreads -lsocket -Igthreads.
• Библиотеки разработки SCO являются реентерабельными в FSU Pthreads. SCO
требует от функций своих библиотек реентерабельности, поэтому они должны
быть таковыми и в FSU Pthreads. FSU Pthreads в OpenServer пытается использо-
вать схему SCO создания реентерабельных библиотек.
• FSU Pthreads (по крайней мере, версия из сайта http://www.mysql.com/) по-
ставляется скомпонованной с GNU ma 11 ос. Если вы обнаружите проблемы с
использованием памяти, убедитесь, что gmalloc.o включен в l i b g t h r e a d s . a и
libgthreads.so.
• В FSU Pthreads следующие системные вызовы работают с потоками pthread:
r e a d ( ) , w r i t e ( ) , getmsg(), connect(), a c c e p t ( ) , s e l e c t ( ) и w a i t ( ) .
• Исправление CSSA-2001-SCO.35.2 (упомянуто в списке как "erg711905-
dscrremap security patch (version 2.0.0)") нарушает работу потоков FSU и делает
mysqld нестабильным. Если вы хотите запускать mysqld на машине под управле-
нием OpenServer 5.0.6, его потребуется удалить.
• SCO предоставляет исправления для операционных систем OpenServer 5.0.x по
адресу ftp://ftp.sco.com/pub/openserver5.
• SCO предоставляет для OpenServer 5.0.x исправления, касающиеся защиты и
libsocket.so.2, по адресам ftp://ftp.sco.com/pub/security/OpenServer и
ftp://ftp.sco.com/pub/security/sse.
• Исправления защиты для систем до OSR506. Исправления для telnetd дос-
тунпы по адресу ftp://stage.caldera.com/pub/security/openserver/ или
ftp://stage.caldera.com/pub/security/openserver/CSSA-2001-SCO.10/; там же
196 Глава 2. Установка MySQL

находятся исправления для обеих библиотек - l i b s o c k e t . so. 2 и l i b r e s o l v . so. 1 - с


инструкциями по установке в системах с версиями до OSR506. Возможно, имеет
смысл установить эти ичсправления перед попытками компиляции и применения
MySQL.

2.6.5.9. Замечания по SCO UnixWare версии 7.1.x


В среде UnixWare 7.1.0 необходимо использовать версию MySQL, начиная с 3.22.13,
чтобы получить исправления проблем переносимости и проблем операционной системы.
Мы компилируем MySQL в UnixWare версии 7.1.x, используя следующую команду
configure:
СС=сс СХХ=СС ./configure —prefix=/usr/local/mysql
Если вы хотите воспользоваться компилятором дсс, то должны иметь версию дсс
2.95.2 или более новую.
СС=дсс СХХ=д++ ./configure —prefix=/usr/local/raysql
S C O предлагает исправления д л я о п е р а ц и о н н ы х с и с т е м U n i x W a r e 7.1.1 и 7.1.3 н а
ftp://ftp.sco.com/pub/unixware7, а для OpenUNIX 8.0.0 - на ftp://ftp.sco.com/pub/
openunix8.
Информацию об исправлениях в системе безопасности SCO можно найти по ад-
ресу ftp://ftp.sco.com/pub/security/OpenUNIX для систем OpenUnix и по адресу
ftp://ftp.sco.com/pub/security/UnixWare для систем UnixWare.

2.6.6. Замечания по OS/2


MySQL использует довольно много открытых файлов. В связи с этим вам придется
добавить в файл CONFIG.SYS строку, подобную следующей:
SET EMXOPT=-c - п - Ы 0 2 4

Если этого не сделать, скорее всего, вы столкнетесь с описанной ниже ошибкой:


File 'xxxx' not found (Errcode: 24)
При работе с MySQL в OS/2 Warp 3 необходимо, чтобы в системе был установлен
пакет FixPack 2.9 или выше. Для OS/2 Warp 4 нужен FixPack 4 или выше. Это требова-
ние накладывается библиотекой Pthreads. MySQL должен быть установлен в разделе
диска, поддерживающем длинные имена файлов, таком как HPFS, FAT32 и так далее.
Сценарий INSTALL.CMD должен запускаться через собственный командный интерпре-
татор OS/2 CMD.EXE, поскольку он может не работать в среде альтернативных оболочек
вроде 4OS2.EXE.
Сценарий s c r i p t s / m y s q l - i n s t a l l - d b переименован. Теперь он называется
i n s t a l l . c m d и является REXX-сценарием, который устанавливает параметры безопасно-
сти MySQL по умолчанию и создает пиктограмму Workplace Shell для MySQL.
Поддержка динамических модулей скомпилирована, но еще недостаточно протести-
рована. Динамические модули должны компилироваться с использованием библиотеки
времени выполнения Pthreads.
gcc - Z d l l -Zmt - Z c r t d l l = p t h r d r t l - I . . / i n c l u d e - I . . / r e g e x - I . . \
-o example udf_example.cc - L . . / l i b - l m y s q l c l i e n t udf_example.def
mv e x a m p l e . d l l example.udf
2.7. Замечания по поводу установки Perl 197

- На заметку!
; В связи с ограничениями, накладываемыми OS/2, длина имен модулей UDF не должна превы-
шать 8 символов (без расширения). Модули расположены в каталоге /mysql2/udf. Сценарий
- safe-mysqld.cmd помещает этот каталог в переменную окружения BEGINLIBPATH. При ис-
' пользовании UDF-модулей указанные расширения имен игнорируются. Предполагается, что они
'-' всегда будут .udf. Например, в Unix разделяемый модуль может иметь имя example.so и
функции из него будет загружаться следующим образом:
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME ' e x a m p l e . s o ' ;

В среде OS/2 модуль должен называться example.udf, но указывать его расширение


не придется:
1
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME ' e x a m p l e ;

2.6.7. Замечания по BeOS


Некоторые разработчики BeOS сообщали нам, что MySQL перенесен в среду опера-
ционной системы BeOS на 80%, однако уже долгое время мы не получали от них допол-
нительных новостей.

2.7. Замечания по поводу установки Perl


Поддержка языка Perl для MySQL обеспечивается за счет предоставления клиентско-
го интерфейса DBI/DBD. Этот интерфейс требует наличия Perl версии 5.6.0 или более
поздней. Он не работает для старых версий Perl.
Если вы хотите применять транзакции вместе с Perl DBI, вам понадобится модуль
DBI: :mysql версии 1.2216 или более новый. Рекомендуется версия 2.9003 и выше.
Если вы используете клиентскую библиотеку MySQL 4.1, вам понадобится
DBI: :mysql версии 2.9003 или выше.
Начиная с MySQL 3.22.8, поддержка Perl больше не входит в состав дистрибу-
тива MySQL. Вы можете получить необходимые модули для Unix на сайте
http://search.cpan.org, или воспользоваться программой ActiveState ppm в среде
Windows. В последующих разделах описано, как это сделать.
Поддержку Perl для MySQL следует устанавливать, если вы хотите запускать сцена-
рии тестов производительности. См. раздел 6.1.4.

2.7.1. Установка Perl под Unix


Поддержка Perl для MySQL требует, чтобы на машине была установлена поддержка
клиентских программ MySQL (библиотеки и заголовочные файлы). Большинство спосо-
бов установки по умолчанию копируют все необходимые файлы. Однако если вы уста-
навливаете MySQL под Linux из RPM-файлов, убедитесь, что у вас установлен RPM-
модуль разработчика. Клиентские программы находятся в клиентском RPM-модуле, од-
нако поддержка для программирования - в RPM-модуле разработчика.
Файлы, необходимые для установки поддержки Perl, можно получить из CPAN
(Copmrehensive Perl Archive Network) по адресу h t t p : //search. cpan. org.
Простейший способ установки Perl под Unix предполагает использование CPAN-
модулей. Например:
shell> perl -MCPAN -e shell
cpan> i n s t a l l DBI
cpan> i n s t a l l DBD::mysql
198 Глава 2. Установка MySQL

Установка DBD: :mysql выполняет множество тестов. Эти тесты должны иметь воз-
можность подключаться к локальному серверу MySQL от имени анонимного пользова-
теля без пароля. Если вы уже удалили анонимные учетные записи или назначили им па-
роли, тесты не запустятся. С помощью force i n s t a l l DBD: rraysql можно проигнориро-
вать тесты, завершившиеся неудачей.
DBI требует наличия модуля Data::Dumper. Возможно, он уже установлен. Если нет,
его нужно установить до установки DBI.
Можно также загрузить дистрибутивы модулей в форме сжатого архива t a r и со-
брать их вручную. Например, процедура распаковки и сборки дистрибутив DBI выглядит
следующим образом:
1. Распакуйте дистрибутив в текущем каталоге:
shell> gunzip < DBI-ВЕРСИЯ.tar.gz | tar xvf -
Эта команда создает каталог по имени DBI-ВЕРСИЯ.
2. Перейдите в корневой каталог распакованного дистрибутива:
shell> cd ЬЫ-ВЕРСИЯ
3. Выполните сборку дистрибутива с компиляцией всех кодов:
shell> perl Makefile.PL
shell> make
shell> make test
shell> make install
Команда make t e s t важна, поскольку она проверяет работоспособность модуля.
Помните, что когда вы запускаете эту команду во время установки модуля DBD: :mysql,
сервер MySQL должен быть запущен, иначе тесты не пройдут.
Неплохо переустанавливать DBD::mysql всякий раз, когда устанавливается новый
выпуск MySQL, особенно, если вы видите, что ваши DBI-сценарии перестали работать
после обновления MySQL.
Если у вас нет прав доступа для установки модулей Perl в системный каталог, или ес-
ли вы хотите установить их локально, следующая ссылка может в этом помочь:
http://servers.digitaldaze.com/extensions/perl/modules.htrallmodules.
Читайте материал под заголовком "Installing New Modules that Require Locally
Installed Modules" ("Установка новых модулей, которые требуют локально установлен-
ных модулей").

2.7.2. Установка ActiveState Perl под Windows


Для того чтобы установить модуль DBD MySQL с ActiveState Perl под Windows, необ-
ходимо:
• Получить ActiveState Perl по адресу http://www.activestate.com/Products/
ActivePerl/ и установить его.
• Открыть консольное окно ("окно DOS").
• Если необходимо, установить переменную окружения НТТРргоху, например, так:
set HTTP_proxy=my.proxy,com:3128
• Запустить программу PPM:
С:\> C:\perl\bin\ppm.pl
2.7. Замечания по поводу установки Perl 199

• Установить DBI, если это еще не сделано:


ppm> install DBI
• Если все прошло успешно, запустить следующую команду:
install \
ftp://ftp.de.uu.net/pub/CPAN/authors/id/JWIED/DBD-raysql-l.2212.x86.ppd
Эта процедура должна работать, по крайней мере, с ActiveState Perl версии 5.6.
Если же данную процедуру выполнить не удается, вам придется установить вместо
этого драйвер MyODBC и подключаться к серверу MySQL через ODBC:
use DBI;
$dbh= DBI->connect("DBI:ODBC:$dsn",$user,$password) ||
die "Ошибка $DBI::errstr при подключении к $dsn\n";

2.7.3. Проблемы использования интерфейса Perl DBI/DBD


Если Perl сообщает, что не может обнаружить модуль .. /mysql/mysql. so, это значит,
что он не может найти разделяемую библиотеку libmysql client .so.
Это можно исправить одним из следующих методов:
• Скомпилировать дистрибутив DBD: :mysql с помощью команды perl Makefile.PL
- s t a t i c -config вместо perl Makefile.PL.
• Скопировать библиотеку libmysqlclient. so в каталог, в котором хранятся другие
разделяемые библиотеки (предположительно, /usr/lib или /lib).
• Модифицировать опции -L, используемые для компиляции DBD: :mysql, чтобы они
отражали реальное местоположение libmysqlclient .so.
• В среде Linux можно добавить путь к каталогу, содержащему libmysqlclient.so,
в файл /etc/Id.so.conf.
• Добавить путь к каталогу, содержащему libmysqlclient.so, в переменную окру-
жения LDRUNPATH. Некоторые системы используют вместо нее переменную
LD_LIBRARY_PATH.
Имейте в виду, что возможно, вам также понадобится модифицировать опции -L, ес-
ли имеются и другие библиотеки, которых компоновщик не может найти. Например,
если он не находит libc, потому что она находится в /lib, а команда компоновки ука-
зывает -L/usr/lib, измените эту опцию на -L/lib или добавьте ее в команду вызова
компоновщика.
Если DBD::mysql выдает приведенные ниже ошибки, вероятно, вы используете дсс
(или старый бинарный код, скомпилированный с помощью дсс):
/usr/bin/perl: can't resolve symbol ' moddi3'
/usr/bin/perl: can't resolve symbol ' divdi3'
Добавьте опцию -L/usr/lib/gcc-lib/... -lgcc к команде вызова компоновщика
при сборке библиотеки mysql.so (проверяйте вывод make для mysql.so, когда компили-
руете Perl-клиент). Опция -L должна указывать путь к каталогу, в котором в вашей сис-
теме хранится библиотека libgcc. a.
Другая причина возникновения этой проблемы может состоять в том, что Perl и
MySQL не скомпилированы одним и тем же компилятором, то есть дсс. В этом случае
их потребуется перекомпилировать с помощью дсс.
200 Глава 2. Установка MySQL

При запуске тестов вы можете получить следующее сообщение об ошибке от


DBD::mysql:
t/OObase install_driver(mysql) failed:
Can't load '../blib/arch/auto/DBD/mysql/mysql.so' for module DBD::mysql:
../blib/arch/auto/DBD/mysql/mysql.so: undefined symbol:
uncompress at /usr/lib/perl5/5.00503/i586-linux/DynaLoader.pm line 169.
Это означает, что вы должны включить библиотеку сжатия -lz в строку компоновки.
Это можно сделать, изменив строку файла lib/DBD/mysql/Install .pm с
$sysliblist .= " -lm";
на
$sysliblist .= " -lm -lz";
После этого вы должны запустить make realclean и после этого выполнить установ-
ку сначала.
Если вы собираетесь устанавливать DBI в среду SCO, то должны отредактировать
файлы Makefile в DBl-xxx и всех его подкаталогах. Помните, что это предполагает ис-
пользование компилятора дсс 2.95.2 или более нового:
Старый: Новый:
СС = ее СС = дсс
CCCDLFLAGS = -KPIC -Wl,-Bexport CCCDLFLAGS = -fpic
CCDLFLAGS = -wl,-Bexport CCDLFLAGS =

LD = Id LD = gee -G -fpic
LDDLFLAGS = -G -L/usr/local/lib LDDLFLAGS = -L/usr/local/lib
LDFLAGS = -belf -L/usr/local/lib LDFLAGS = -L/usr/local/lib

LD = Id LD = gec -G -fpic
OPTIMISE = -Od OPTIMISE = -01

Старый:
CCCFLAGS = -belf -dy -wO -U M_XENIX -DPERL_SC05 -I/usr/local/include

Новый:
CCFLAGS = -U M_XENIX -DPERL_SC05 -I/usr/local/include

Эти исправления необходимы, поскольку динамический загрузчик не сможет загру-


зить модули DBI, если они скомпилированы с помощью ice или ее.
Если вы хотите использовать модули Perl в системах, не поддерживающих динами-
ческую компоновку (таких как SCO), можете сгенерировать статическую версию Perl,
включающую в себя модуль DBD::mysql. Способ заставить это работать состоит в том,
чтобы сгенерировать собственную версию Perl со статически скомпонованным в нее
кодом DBI и затем установить его поверх существующей версии Perl. Затем необходимо
использовать его для статической компоновки с кодом модуля DBD и утсановить еще раз.
На SCO нужно иметь следующие установки переменных окружения:
LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib:/usr/progressive/lib
2.7. Замечания по поводу установки Perl 201

или:
LD_LIBRARY_PATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:\
/usr/progressive/lib:/usr/skunk/lib
LIBPATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:\
/usr/progressive/lib:/usr/skunk/lib
MANPATH=scohelp:/usr/man:/usr/locall/man:/usr/local/man:\
/usr/skunk/man:
Сначала выполните сборку Perl, включающую скомпонованный статически модуль
DBI, запустив в каталоге, в котором находится дистрибутив DBI, следующие команды:
shell> perl Makefile.PL -static -config
shell> make
shell> make install
shell> make perl
Затем необходимо установить новую версию Perl. Вывод команды make perl пока-
жет явно все команды make, которые нужно выполнить для целей установки. В среде
SCO это будет make -f Makefile.aperl inst_perl MAP_TARGET=perl.
После этого, используя только что собранную версию Perl, создайте другую версию
Perl, которая статически включает модуль DBD: :mysql, выполнив приведенные ниже ко-
манды в каталоге, в котором расположен дистрибутив DBD: :mysql:
shell> perl Makefile.PL -static -config
shell> make
shell> make install
shell> make perl
И, наконец, установите этот новый вариант Perl. Опять-таки, вывод make perl пока-
жет все команды make, которые необходимо будет выполнить для установки.
3

Использование
программ MySQL

В настоящей главе дается краткий обзор программ, предлагаемых компанией


MySQL AB, и описывается, каким образом задаются опции при работе с ними.
Большинство опций являются специальными для той или иной программы, но синтак-
сис, с помощью которого они задаются, одинаковый для всех программ. В следующих
главах предлагается более подробное описание каждой из программ, включая и то, какие
опции она распознает.

3.1. Обзор программ MySQL


Компания MySQL AB предоставляет несколько типов программ:
• Сервер MySQL и сценарии запуска сервера:
• mysqld - сервер MySQL.
• mysqld_saf e, mysql. server и mysqldjnulti - сценарии запуска сервера.
• mysql_install_db инициализирует каталог данных и начальные базы данных.
Более подробно эти программы рассматриваются в главе 4.
• Клиентские программы, получающие доступ к серверу:
• mysql - клиент командной строки, используемый для выполнения SQL-
операторов в интерактивном режиме или режиме пакетной обработки.
• mysql с с (MySQL Control Center - Центр управления MySQL) представляет со-
бой интерактивный графический инструмент для выполнения SQL-операторов
и администрирования.
• mysqladmin - клиент администрирования.
• mysql check выполняет операции по обслуживанию таблиц.
• mysqldump и mysqlhotcopy - создают резервные копии баз данных.
• mysqlimport импортирует файлы данных.
• mysql show отображает информацию о базах данных и таблицах.
Эти программы более подробно описываются в главе 7.
3.2. Запуск MySQL-программ 203

• Утилиты, которые функционируют независимо от сервера:


• myisamchk выполняет операции по обслуживанию таблиц.
• myisampack генерирует сжатые таблицы, предназначенные только для чтения.
• mysqlbinlog - инструмент для обработки файлов бинарных журналов.
• perror отображает значение кода ошибки.
Описание утилиты myisamchk дается в главе 4, остальные программы
рассматриваются в главе 7.
Большинство дистрибутивов MySQL включают все перечисленные выше программы
кроме тех, которые зависят от конкретной платформы. (Например, сценарии запуска
сервера в среде Windows не используются.) Исключение составляют RPM-дистри-
бутивы, которые являются еще более специализированными: существует отдельный
RPM-пакет для сервера, отдельный RPM-пакет для клиентских программ и так далее.
При отсутствии одной или нескольких программ обратитесь в главу 2, в которой пред-
ставлена информация о типах дистрибутивов MySQL и о конкретном их составе. Может
оказаться так, что придется установить какие-то дополнительные приложения.

3.2. Запуск MySQL-программ


Чтобы запустить программу MySQL из командной строки (то есть из командной обо-
лочки или командной строки), введите имя программы, после которого укажите опции
или любые другие аргументы, необходимые для того, чтобы сообщить программе, ка-
кую операцию она должна выполнить. Ниже приведены примеры команд, вызывающих
ту или иную программу. "shell>" представляет подсказку командного интерпретатора и
не является частью вводимой команды. То, как именно выглядит подсказка, будет зави-
сеть от конкретного интерпретатора. Типичными являются следующие подсказки: $ для
sh или bash, % для csh или tcsh и С:\> для command.com или cmd.exe в Windows.
shell> mysql test
shell> mysqladmin extended-status variables
shell> mysqlshow —help
shell> mysqldump —user=root personnel
Аргументы, начинающиеся с '-', представляют собой аргументы опций. Обычно через
них задается тип соединения, которое программа должна установить с сервером, или из-
менения, вносимые в режим работы программы. Синтаксис опций описан в разделе 3.3.
Аргументы, не относящиеся к опциям (в начале которых не стоит ' - ' ) , предостав-
ляют дополнительную информацию для программы. Например, программа mysql ин-
терпретирует первый аргумент такого типа (указанный без тире) как имя базы данных;
таким образом, команда mysql t e s t означает, что вы хотите использовать базу данных
с именем t e s t .
В последних разделах, посвященных отдельным программам, перечисляются распо-
знаваемые той или иной программой опции и разъясняются любые дополнительные ар-
гументы помимо тех, что используются для опций.
Некоторые опции являются общими для большинства программ. Основные из них -
это опции —host, —user и —password, с помощью которых задаются параметры соеди-
нения. В них указывается имя главного компьютера (хоста), на котором выполняется
сервер MySQL, а также имя пользователя и пароль используемой учетной записи
MySQL. Все клиентские программы MySQL распознают эти опции и позволяют конкре-
204 Глава 3. Использование программ MySQL

тизировать, к какому серверу будет производиться подключение, и какая учетная запись


на нем будет использоваться.
Для вызова программ MySQL может понадобиться указать путь к каталогу bin, в ко-
тором они установлены. Чаще всего это необходимо в том случае, когда вы получаете
ошибку наподобие "program not found" ("программа не найдена") при каждой попытке
запуска программы MySQL из каталога, отличного от bin. Для удобства можно добавить
имя пути к каталогу bin в переменную окружения PATH. Тогда, чтобы запустить про-
грамму, потребуется указать только ее имя, а не весь путь.
Для получения более подробной информации о настройке PATH смотрите соответст-
вующую документацию по командному интерпретатору, поскольку синтаксис, исполь-
зуемый для установки переменных окружения, зависит от конкретного интерпретатора.

3.3. Задание опций программы


Существует несколько способов задания опций для программ MySQL:
• Опции можно задавать в командной строке, непосредственно после имени про-
граммы. Чаще всего таким образом задаются опции, применяемые для конкретно-
го вызова программы.
• Опции можно определять в файле опций, который программа считывает во время
запуска. Таким образом лучше задавать те опции, которые вы хотите, чтобы про-
грамма считывала при каждом запуске.
• Опции можно задавать в переменных окружения. Использовать переменные
удобно для тех, опций, которые должны выполняться при каждом запуске про-
граммы, хотя на практике с такой же целью чаще применяются файлы опций. (В
разделе 4.9.2 рассматривается ситуация, когда переменные окружения могут ока-
заться очень полезными: они используются для того, чтобы задать TCP/IP-порт и
файл Unix-сокета для сервера и для клиентских программ одновременно.)
Для определения указанных опций программы MySQL сначала просматривают пере-
менные окружения, потом файл опций и только после этого командную строку. Если
опция задана несколько раз, использоваться будет то ее значение, которое встречается
последним. Это означает, что значения переменных окружения обладают самым низким
приоритетом, а значения опций командной строки - самым высоким.
Воспользоваться преимуществом такого вида обработки опций программами
MySQL можно следующими образом: в файле опций для опций программы укажите
значения по умолчанию, тогда эти опции не придется вводить при каждом запуске про-
граммы, но зато всегда при необходимости их можно будет перекрыть, задав нужные
значения в командной строке.

3.3.1. Использование опций в командной строке


Существуют следующие правила для задания программных опций в командной строке:
• Опции указываются после имени команды.
• Аргумент опции всегда начинается с одиночного или двойного тире ('-' или ' — ' ) ,
в зависимости от того, коротким или длинным является ее название. Многие оп-
ции принимают обе формы. Например, -? и —help представляют собой краткий и
длинный варианты опции, сообщающей программе MySQL о необходимости вы-
вести справочную информацию.
3.3. Задание опций программы 205

• Имена опций чувствительны к регистру символов. Опции -v и -V являются


допустимыми, но совершенно разными (это краткие формы опций --verbose и
—version соответственно).
• Некоторые опции принимают значение, следующее за названием опции. Напри-
мер, -h localhost и --host=localhost указывают клиентской программе хост
сервера MySQL. Значение опции сообщает программе имя хоста, на котором вы-
полняется сервер MySQL.
• Когда используется длинный вариант названия опции, принимающей значения,
название опции и присваиваемое значение следует разделять знаком '='. В случае
использования краткого варианта названия опции, принимающей значения, зна-
чение может следовать сразу за буквенным символом опции или отделяться от не-
го пробелом, (-hlocalhost и -h localhost эквивалентны). Исключением из этого
правила является опция для задания пароля MySQL. Она может указываться в
длинном варианте как — password=3Ha<jeHne_napcui# или --password. В последнем
случае (когда значение пароля отсутствует), программа предложит ввести пароль.
Может также применяться короткая форма этой опции -рзначение_пароля или -р.
Однако если используется короткая форма и указывается значение пароля, пробел
между буквенным символом опции и значением пароля не ставится. Причина
этого состоит в том, что при наличии пробела программа не может в точности оп-
ределить, является ли следующий за пробелом аргумент значением пароля или же
каким-либо другим аргументом. Поэтому приведенные ниже команды имеют аб-
солютно разные значения:
shell> mysql -ptest
shell> mysql -p test
Первая команда указывает mysql использовать значение t e s t в качестве пароля,
но не задает имя базы данных по умолчанию. Вторая команда указывает mysql на
необходимость запроса пароля, a t e s t трактуется как имя базы данных по умол-
чанию.
MySQL 4.0 предлагает дополнительные возможности для задания опций. Эти изме-
нения были появились в версии MySQL 4.O.2. Часть из них касается способа, которым
задаются опции с режимами "enabled" ("включена") и "disabled" ("отключена"), а также
использования опций, которые присутствуют в одной версии MySQL и отсутствуют в
другой. Упомянутые возможности рассматриваются в данном разделе. К другим изме-
нениям относятся методы применения опций для установки программных переменных.
Этот вопрос более подробно излагается в разделе 3.3.4.
Некоторые опции управляют поведенческими аспектами, которые могут быть вклю-
чены или отключены. Например, клиент mysql поддерживает опцию —column-names,
определяющую, отображать ли строку с именами столбцов в начале результата запроса.
По умолчанию эта опция включена. Однако в некоторых случаях ее может понадобиться
отключить, например, при отправке выходных данных mysql в другую программу, ожи-
дающую получить только данные, а не строку начальных заголовков.
Для отключения —column-names допускается использование следующих вариантов:
—disable-column-names
—skip-column-names
—column-names=0
206 Глава 3. Использование программ MySQL

Указание префикса -disable или префикса -skip, или же суффикса =0 приводит к


одному и тому же результату - опция будет отключена.
Форма включения для данной опции может указываться следующими способами:
—column-names
—enable-column-names
—column-names=l
Еще одним изменением, касающимся обработки опций, которое было введено в
MySQL 4.0, является то, что теперь для опций командной строки можно использовать
префикс —loose. Когда перед опцией указывается такой префикс, программа, если она
не распознает опцию, не завершает работу с выдачей сообщения об ошибке, а вместо
этого отображает только предупреждение:
shell> mysql —loose-no-such-option
mysql: WARNING: unknown option '—no-such-option'
mysql: ПРЕДУПРЕЖДЕНИЕ: неизвестная опция ' —no-such-option'
Использование префикса —loose может пригодиться, если программы запускаются
сразу из нескольких установок MySQL на одном компьютере, по крайней мере, в тех
случаях, когда версии установок не ниже 4.0.2. Этот префикс особенно полезен, когда
опции перечисляются в файле опций. Опция, которая не распознается ни одной версией
данной программы, может указываться с префиксом --loose (или loose в файле опций).
Версии программы, которые не распознают эту опцию, будут выдавать соответствую-
щее предупреждение и игнорировать ее. Для применения такого метода требуется, что-
бы все используемые версии соответствовали версии MySQL 4.0.2 или выше, поскольку
более старые версии не распознают обозначение --loose.

3.3.2. Использование файлов опций


Программы MySQL могут считывать опции запуска из файлов опций (которые еще
иногда называют "конфигурационными файлами"). Такие файлы обеспечивают удобный
способ задания наиболее часто используемых опций, так что необходимость вводить эти
опции в командной строке при каждом запуске программы отпадает. Файлы опций дос-
тупны, начиная с версии MySQL 3.22.
Программы, поддерживающие файлы конфигурации, следующие: myisamchk,
myisampack, mysql, mysql.server, mysqladmin, mysqlbinlog, mysqlcc, mysqlcheck, mysqld,
mysqld_safe, mysqldump, mysqlhotcopy, mysqlimport и mysqlshow.
В среде Windows программы MySQL считывают опции запуска из следующих файлов:

Имя файла Назначение


KATAJIOr_WINDOWS\my. i n i Глобальные опции.
С: \my. cnf Глобальные опции.

KATAJlor_WlNDOWS представляет расположение каталога вашей копии Windows. Чаще


всего это C:\Windows или C:\WinNT. Точное местонахождение каталога можно опреде-
лить с помощью переменной окружения, воспользовавшись следующей командой:
С:\> echo %WINDIR%
В среде Unix программы MySQL считывают опции запуска из следующих файлов:
3.3. Задание опций программы 207

Имя файла Назначение


/etc/ray.cnf Глобальные опции.
КАТАЛОГ_ДАННЫХ/ту. c n f Специальные опции для сервера.
defaults-extra-file Файл, заданный через —defaults-extra-fПе=луть,
если он существует.
~ /. my. enf Специальные опции для пользователя.

КАТАЛОГ_ДАННЫХ представляет расположение каталога данных MySQL. Обычно это


/usr/local/mysql/data для бинарной установки или /usr/local/var - для исходной.
Обратите внимание, что это каталог данных, который был указан во время конфигура-
ции, а не каталог, заданный с помощью —datadir при запуске mysqld. Использование
—datadir во время выполнения не влияет на то, где сервер будет искать файлы опций,
потому делает он это перед тем, как приступает к обработке аргументов командной строки.
MySQL ищет файлы опций в описанном выше порядке и, если они существуют, счи-
тывает их. При наличии сразу нескольких файлов опций, опция, которая указана в фай-
ле, считанном позже, будет иметь преимущественное значение по сравнению с такой же
опцией, указанной в файле, считанном раньше.
Любая опция, которая может быть задана в командной строке во время работы с про-
граммой MySQL, может быть задана и в файле опций. Для получения списка доступных
для данной программы опций, запустите ее с опцией —help.
Синтаксис, с помощью которого задаются опции в файле опций, подобен синтаксису,
используемому в командной строке, за исключением того, что двойное тире в начале
имени опции можно опустить.
Например, в командной строке указывается —quick и —host=localhost, а файле оп-
ций указывается quick и host=localhost. Опция — loose-имя_опции в файле опций зада-
ется в виде 1 ооse-имя^опции.
Пустые строки в файлах опций игнорируются, а непустые могут принимать любую
из следующих форм:
• комментарий
;комментарий
Строки комментариев начинаются с '#' или ' ; ' . В версии MySQL 4.0.14 и выше
комментарий '#' может начинаться также и с середины строки.
• [группа)
группа - это имя программы или группы, для которой устанавливаются опции.
После строки группы все остальные строки типа имя_опции или set-variable бу-
дут относиться к названной группе до конца файла или пока не будет указана дру-
гая строка группы.
• имя_опции
Данная форма эквивалента —имя_опции в командной строке.
• имя_ опции=значение
Данная форма эквивалентна —имя_опции= значение в командной строке. В файле
опций перед и после знака '=' можно поставить пробел, в командной строке это
делать нельзя. Начиная с версии MySQL 4.0.16, для указания значения использу-
ются как двойные, так и одинарные кавычки. Это может пригодиться, если значе-
ние содержит символ комментария '#' или пробел.
208 Глава 3. Использование программ MySQL

• set-variable = имя_переменной=значение
Устанавливает определенное значение программной переменной имя_переменной.
Данная форма эквивалентна —зеЬчаг1аЫе=имя_переменной=значение в команд-
ной строке. Пробелы можно ставить перед и после первого знака '=', но никак не
перед и после второго. Начиная с версии MySQL 4.0, такой синтаксис считается
устаревшим. Для получения более подробной информации об установке про-
граммных переменных обратитесь в раздел 3.3.4.
Пробельные символы в начале и в конце имен и значений опций автоматически уда-
ляются. Для отображения символов забоя, табуляции, новой строки, возврата каретки,
обратной косой черты и пробела в значениях опций можно использовать следующие
управляющие последовательности: *\b\ ' \ t ' , '\n\ '\г', '\\' и '\s\
В среде Windows путь должен указываться в опции с использованием разделителя
7 \ а не '\\ Если требуется применять символ *\\ его необходимо удвоить, то есть '\\\
поскольку символ ' \' в MySQL является управляющим.
Если название группы опций и название программы совпадают, опции, указанные в
группе, будут применяться конкретно для данной программы.
Группа опций [client] считывается всеми клиентскими программами (но не mysqld).
Это позволяет задавать в ней опции, которые будут применяться для каждого клиента.
Например, группа [client] идеально подходит для того, чтобы указать в ней пароль,
который используется вами для подключения к серверу. (Обязательно убедитесь, что
доступ по чтению и записи имеется только у вас, чтобы другие пользователи не смогли
узнать ваш пароль.) Прежде чем вносить опцию в группу [client], проверьте, распозна-
ется ли она всеми используемыми клиентскими программами. Те программы, которым
данная опция неизвестна, после запуска сразу же завершат работу, предварительно вы-
дав сообщение об ошибке.
Начиная с версии MySQL 4.0.14, можно создавать группы опций, которые должны
считываться только одной конкретной серией впусков сервера mysqld, используя для
этих групп имена наподобие [mysqld-4.0], [mysqld-4.1 ] и так далее. Следующая груп-
па указывает, что опция —new должна применяться только серверами MySQL с номера-
ми версий 4.0.x:
[mysqld-4.О]
new
Ниже показан пример типичного файла глобальных опций:
[client]
port=3306
socket=/tmp/mysql.sock
[mysqld]
port=3306
socket=/tmp/mysql.sock
key_buffer_size=16M
max_allowed_packet=8M
[mysqldump]
quick
В этом файле опций используется синтаксис имя_переменной= значение для строк,
устанавливающих значения переменных key_buffer_size и max_allowed_packet.
3.3. Задание опций программы 209

В версиях, предшествующих MySQL 4.0.2, вместо этого следует использовать синтаксис


set-variable (описанный ранее в этом разделе).
Ниже можно видеть пример типичного файла пользовательских опций:
[client]
# Следующий пароль будет отправлен всем стандартным клиентам MySQL
password="my_password"
[mysql]
no-auto-rehash
set-variable = connect_timeout=2
[mysqlhotcopy]
interactive-timeout
В этом файле для установки переменной connect_timeout применяется синтаксис
set-variable. Начиная с версии MySQL 4.0.2, значение переменной можно установить и
просто как connect_timeout=2.
Если установлен исходный дистрибутив, образцы файлов опций с именами
my-xxxx.cnf можно найти в каталоге support-files. Если установлен бинарный дистри-
бутив, то папку support-files следует искать в каталоге установки MySQL (обычно это
C:\mysql в Windows, и /usr/local/mysql в Unix). На текущий момент там предложены
образцы для малых, средних, больших и очень больших систем. Чтобы поэксперименти-
ровать с одним из таких файлов, скопируйте его в C:\my.cnf (Windows) или в файл
. my. cnf домашнего каталога (Unix).
$ На заметку!
Ц. В Windows расширение файла опций .cnf может не отображаться.
Все программы MySQL, которые поддерживают файлы опций, используют следую-
щие опции командной строки:
• —no-defaults. He считывать файлы опций.
• —print-defaults. Выводить имя программы и все опции, получаемые из конфи-
гурационных файлов.
• —defaults-file=HM#_nyTH. Использовать только данный файл опций. имя_пути-
это полный путь к файлу. ^
• --defaults-extra-file=HM#_nyTn. Считывать данный файл опций после файла
глобальных опций, но перед файлом пользовательских опций. имя_пути - это
полный путь к файлу.
Для корректной работы опций необходимо, чтобы каждая из них следовала сразу же
за именем команды в командной строке, за исключением опции —print-defaults, кото-
рая может указываться сразу после —defaults-file или —defaults-extra-file.
В основных сценариях для выполнения синтаксического анализа файлов опций ис-
пользуйте программу m y p r i n t d e f a u l t s . Ниже показан пример возможных выходных
данных этой программы при запросе отобразить опции, которые будут найдены в груп-
пах [client] и [mysql]:
shell> myj?rint_defaults client mysql
~port=3306
—socket=/tmp/mysql.sock
—no-auto-rehash
210 Глава 3. Использование программ MySQL

. На заметку!
р. Разработчикам стоит помнить следующее. Анализ файлов опций выполняется в клиентской биб-
§ лиотеке С просто путем обработки всех совпадающих опций (то есть опций, находящихся в COOT-
IE ветствующих группах) до обработки любых аргументов, указываемых в командной строке. Это
| прекрасно подходит для программ, использующих последний из всех встречающихся экземпля-
|| ров опции, которая была задана несколько раз. При наличии программы С или C++, которая мо-
%'t жет обрабатывать многочисленные заданные опции, но не может считывать файлы опций, по-
§- требуется добавить только две строки, чтобы предоставить ее возможность делать это. Про-
Й смотрите исходный код любого из стандартных клиентов MySQL, чтобы узнать, как добиться
jf такого результата.

Интерфейсы к MySQL для других языков основаны на клиентской библиотеке С, и


некоторые из них обеспечивают способ получения доступ к содержимому файлов опций.
К ним относятся интерфейсы для языков Perl и Python. Более подробную информацию
можно найти в документации по выбранному интерфейсу.

3.3.3. Использование переменных окружения


для задания опций
Чтобы задать опцию с помощью переменной окружения, установите значение пере-
менной, применяя синтаксис, подходящий для вашего процессора комментариев. На-
пример, в Windows или NetWare для задания имени учетной записи MySQL можно уста-
новить переменную USER. Для этого применяется следующий синтаксис:
SET USER=ваше_имя
В среде Unix синтаксис будет зависеть от командной оболочки. Предположим, необхо-
димо задать порт TCP/IP через переменную MYSQL__TCP_PORT. Для командной оболочки
Bourne и ее вариаций (sh, bash, zsh и так далее) синтаксис выглядит следующим образом:
MYSQLJTCP_PORT=3306
Для оболочек c s h n t c s h синтаксис будет таким:
setenv MYSQL_TCP_PORT 3306
Команды по установке переменных окружения могут выполняться непосредственно
из командной строки, при этом они немедленно вступают в силу. Такие настройки будут
действовать вплоть до выхода из программы. Чтобы эти же настройки действовали каж-
дый раз при входе в программу, необходимо поместить их в соответствующую команду
или команды в файле запуска, который считывается интерпретатором команд перед ка-
ждым запуском. Типичными файлами запуска являются: AUTOEXEC.BAT (для Windows),
.bash_profile (для bash) и .tcshrc (для tcsh). Дополнительную информацию можно
найти в документации по интерпретатору команд.
В приложении Б перечислены все переменные окружения, которые оказывают влия-
ние на работу программ MySQL.

3.3.4. Использование опций для установки


программных переменных
В большинстве программ MySQL существуют внутренние переменные, которые
можно устанавливать и во время выполнения. Начиная с версии MySQL 4.0.2, про-
граммные переменные устанавливаются так же, как и любая опция с длинным именем,
принимающая значение. Например, в mysql существует переменная max_allowed_packet,
3.3. Задание опций программы 211

с помощью которой контролируется максимальный размер коммуникационного буфера.


Чтобы в mysql установить для этой переменной значение 16 Мбайт, воспользуйтесь од-
ной из следующих команд:
shell> mysql --max_allowed_packet=16777216
shell> mysql —max_allowed_packet=16M
Первая команда указывает значение в байтах, а вторая - в мегабайтах. В качестве
суффикса могут применяться символы К, м или G (как в верхнем, так и в нижнем регист-
ре), обозначающие единицы измерения - килобайты, мегабайты или гигабайты соответ-
ственно.
В файле опций двойное тире перед названием переменной не ставится:
[mysql]
max_allowed_packet=16777216
Можно записать и так:
[mysql]
max_allowed_packet=l6M
По желанию символы подчеркивания ('_') в имени переменной могут заменяться
знаками тире ('-').
В версиях, предшествующих MySQL 4.0.2, имена программных переменных не рас-
познаются как имена опций. Поэтому для присвоения переменной значения необходимо
пользоваться опцией —set-variable:
shell> mysql ~set-variable=max__allowed_packet=16777216
shell> mysql —set-variable=max_allowedjpacket=16M
В файле опций двойное тире ('--') перед названием опции опускается:
[mysql]
set-variable = max_allowed_packet=16777216
Или так:
[mysql]
set-variable = max_allowed_packet=16M
В версиях MySQL, предшествующих 4.0.2, при использовании опции --set-variable
знаки подчеркивания в именах переменных заменять знаками тире нельзя.
Опция —set-variable по-прежнему распознается в версиях MySQL 4.0.2 и выше,
однако считается устаревшей.
Некоторые серверные переменные можно устанавливать во время выполнения. Более
подробная информация по данному вопросу представлена в разделе 4.23Л.2.
4

Администрирование
баз данных

fcrf настоящей главе описаны вопросы, касающиеся администрирования установлен-


и и ^ ной копии MySQL, а именно - конфигурирование сервера, управление пользова-
тельскими учетными записями и выполнение резервного копирования.

41. Сервер MySQL и сценарии запуска сервера


Сервер MySQL - mysqld - это главная программа, выполняющая большую часть ра-
боты в рамках установленной копии MySQL. Вместе с сервером идут еще несколько
сценариев, которые выполняют операции запуска во время установки MySQL или пред-
ставляют собой вспомогательные программы, оказывающие помощь при запуске или
останове сервера.
В этом разделе предлагается обзор самого сервера и связанных с ним программ, а
также информация о сценариях запуска. Сведения о конфигурировании сервера можно
найти в разделе 4.2.

4.1.1. Обзор серверных сценариев и утилит


Все программы MySQL используют огромное число различных опций. Однако каж-
дая из них распознает специальную опцию —help, с помощью которой можно получить
описание принимаемых данной программой опций. Например, попробуйте запустить
mysqld —help.
Для всех стандартных программ опции по умолчанию можно переопределить, указав
необходимые из них в командной строке или файле опций (см. раздел 3.3).
В приведенном ниже списке представлены краткие описания MySQL-сервера и свя-
занных с ним программ:
• mysqld. Демон SQL (то есть сервер MySQL). Для работы клиентских программ
необходимо, чтобы mysqld был запущен и успешно функционировал, поскольку
клиенты получают доступ к базам данных через соединение с сервером. См. раз-
дел 4.2.
• mysqld-max. Версия сервера, предлагающая дополнительные функциональные
возможности. См. раздел 4.1.2.
4.1. Сервер MySQL и сценарии запуска сервера 213

• mysqld_safe. Сценарий запуска сервера. mysqld_safe пытается запустить сервер


mysqld-max, если он существует, в противном случае запускает mysqld. См. раздел
4.1.3.
• mysql. server. Сценарий запуска сервера. Применяется в системах, использующих
каталоги запуска, в которых содержатся сценарии, запускающие системные служ-
бы для определенных уровней выполнения. Он вызывает mysqld_safe для запуска
MySQL-сервера. См. раздел 4.1.4.
• mysqldmulti. Сценарий запуска сервера, который может запускать или останав-
ливать сразу несколько серверов, существующих на системе. См. раздел 4.1.5.
• mysql_install_db. Данный сценарий создает таблицы привилегий MySQL с при-
вилегиями по умолчанию. Обычно используется только один раз - при первой ус-
тановке MySQL в системе.
• mysql_fix_privilege_tables. Данный сценарий используется после модерниза-
ции для внесения в текущие таблицы привилегий любых изменений, появившихся
в новой версии MySQL.
Существуют еще и несколько других программ, которые также запускаются на глав-
ном компьютере сервера:
• myisamchk. Утилита, необходимая для описания, проверки, оптимизации и ис-
правления таблиц My ISAM. Более подробно рассматривается в разделе 4.6.2.
• make_binary_distribution. Данная программа выполняет сборку бинарной вер-
сии скомпилированного MySQL. Для удобства других пользователей MySQL ее
можно впоследствии отправить через FTP в каталог /pub/mysql/upload сайта
ftp.mysql.com.
• mysqlbug. Сценарий, отвечающий за составление отчетов об ошибках в MySQL.
Может использоваться для отправки отчета об ошибке в список рассылки. (Для
описания отчета в онлайновом режиме посетите сайт h t t p : //bugs .mysql.com/.)

4.1.2. Расширенный MySQL-сервер mysqld-max


Сервер MySQL-Мах - это версия MySQL-сервера mysqld, разработанная для под-
держки дополнительных функциональных возможностей.
Выбор используемого дистрибутива зависит от платформы:
• Windows. Бинарный дистрибутив MySQL включает как стандартный сервер
(mysqld.exe), так и сервер MySQL-Max (mysqld-max.exe), поэтому в специальном
дистрибутиве необходимости не будет. Просто воспользуйтесь стандартным ди-
стрибутивом для Windows, который доступен по адресу http://dev.mysql.com/
downloads/mysql-4.0.html. См. раздел 2.2.1.
• Linux. При установке MySQL с помощью дистрибутивов RPM сначала исполь-
зуйте обычный RPM-пакет MySQL-server для установки стандартного сервера под
названием mysqld. Затем, используя RPM-пакет MySQL-Max, установите сервер
mysqld-max. RPM-пакет MySQL-Max предполагает, что RPM-пакет стандартного
сервера уже установлен. Более подробную информацию, касающуюся пакетов
Linux RPM, можно найти в разделе 2.2.2.
214 Глава 4. Администрирование баз данных

• Все остальные дистрибутивы MySQL-Max содержат единственный сервер, назы-


ваемый mysqld, однако обладающий дополнительными функциональными воз-
можностями.
Бинарные дистрибутивы MySQL-Max доступны на Web-сайте MySQL AB по адресу
http://dev.mysql.com/downloads/mysql-max-4.О.html.
Компания MySQL AB выполняет сборку серверов MySQL-Max с использованием
следующих опций конфигурации:
• — with-server-suf f ix=-max. Данная опция добавляет суффикс -max к строке вер-
сии mysqld.
• —with-innodb. Данная опция активизирует поддержку механизма хранения
innoDB. Серверы MySQL-Max всегда включают поддержку innoDB, но фактически
эта опция необходима только для версии MySQL 3.23. Начиная с MySQL 4, меха-
низм хранения InnoDB входит в состав бинарных дистрибутивов по умолчанию,
поэтому для получения поддержки InnoDB сервер MySQL-Max не нужен.
• — with-bdb. Данная опция активизирует поддержку механизма хранения Berkley
DB (BDB).
• CFLAGS=-DUSE_SYMDIR. Данное определение включает поддержку символических
ссылок для Windows.
Бинарные дистрибутивы MySQL-Max удобны для тех, кто хочет устанавливать зара-
нее скомпилированные программы. При сборке сервера с помощью исходного дистри-
бутива появляется возможность создать свой собственный сервер Мах-типа, активизи-
ровав во время конфигурирования те же функции, с которыми собраны бинарные дист-
рибутивы MySQL-Max.
Серверы MySQL-Max включают механизм хранения BDB (Berkeley DB) всегда, когда
это возможно, однако не все платформы поддерживают BDB. Ниже показано, какие плат-
формы обеспечивают такую поддержку для бинарных серверов MySQL-Max, а какие нет.
Система Поддержка BDB
AIX 4.3 Нет
HP-UX 11.0 Нет
Linux-Alpha Нет
Linux-IA-64 Нет
Linux-Intel Да
Mac OS X Нет
NetWare Нет
SCO OSR5 Да
Solaris-Intel Нет
Solaris-SPARC Да
UnixWare Да
Windows/NT Да
Чтобы узнать, какие механизмы хранения поддерживаются сервером, воспользуйтесь
следующим оператором:
mysql> SHOW ENGINES;
4.1. Сервер MySQL и сценарии запуска сервера 215

В версиях, предшествующих MySQL 4.1.2 оператор SHOW ENGINES не доступен. Вме-


сто него используется приведенный ниже оператор, который позволяет проверить зна-
чение переменной для того или иного механизма хранения:
mysql> SHOW VARIABLES LIKE •havejk 1 ;

I Variable_name | Value |
+ + +
I have_bdb | NO I
I have_crypt | YES |
I have_innodb | YES |
I have_isam | NO |
I have_raid | NO |
I have_symlink | DISABLED |
I have_openssl | NO |
I have_query_cache | YES |
+ + +

Значения во втором столбце указывают уровень поддержки сервером той или иной
функции:

Значение Описание
YES Функция поддерживается и активна.
N0 Функция не поддерживается.
DISABLED Функция поддерживается, но была отключена.

Значение N0 указывает, что сервер компилировался без поддержки данной функции,


поэтому о н а не может быть активизирована.
Значение DISABLED появляется либо потому, что сервер запускался с опцией, отклю-
чающей данную функцию, либо потому, что были указаны не все опции, необходимые
для работы с ней. В последнем случае файл журнала ошибок имя_хоста.еп будет со-
держать причину, по которой была отключена данная опция.
С и т у а ц и я , когда появляется значение DISABLED, м о ж е т возникнуть п р и к о м п и л я -
ции InnoDB в M y S Q L 3.23. В M y S Q L 3.23 д л я н а с т р о й к и табличного п р о с т р а н с т в а
InnoDB во в р е м я запуска сервера потребуется указать, п о крайней мере, о п ц и ю
innodb_data_f i l e _ p a t h . Без нее InnoDB сам себя отключит. С м . раздел 9.3. Д л я BDB так-
же можно задавать определенные опции конфигурации, однако даже если этого не де-
лать, BDB автоматически отключаться не будет. См. раздел 8.4.3.
Кроме того, значение DISABLED для InnoDB, BDB или ISAM может появляться и тогда,
когда сервер компилировался с поддержкой таких механизмов хранения, но б ы л запу-
щен с опциями — s k i p - i n n o d b , — s k i p - b d b или — s k i p i s a m .
Начиная с версии 3.23, все серверы M y S Q L поддерживают таблицы My ISAM, посколь-
ку My ISAM является механизмом хранения по умолчанию.

4.1.3. Сценарий запуска сервера mysqldsafe


Сценарий mysqld_safe рекомендуется использовать для запуска сервера mysqld под
управлением ОС Unix и NetWare. mysqld_safe обеспечивает набор дополнительных
функций безопасности, таких как перезапуск сервера в случае ошибки и запись инфор-
216 Глава 4. Администрирование баз данных

мации времени выполнения в журнал ошибок. Особенности функционирования в


NetWare перечислены ниже, в этом же разделе.
£: На заметку!
В версиях, предшествующих MySQL 4.0, сценарий mysqld_saf e называется safe_mysqld. В
/•', целях обратной совместимости бинарные дистрибутивы MySQL еще некоторое время будут
Ь включать s a f e j n y s q l d в качестве символической ссылки на mysqld_safе.

По умолчанию mysqld_safe пытается запустить исполняемый файл с именем


mysqld-max, если таковой существует; в противном случае он запускает mysqld. Обрати-
те внимание на следующие моменты:
• В Linux поведение mysqld_safe имеет определенное значение для MySQL-Max
RPM. RPM устанавливает исполняемый файл с именем mysqld-max, после чего
mysqldsafe будет автоматически использовать этот файл.
• При установке дистрибутива MySQL-Max, который включает сервер mysqld-max,
и последующей модернизации MySQL до версии, отличной от Max, mysqld_safe
будет по-прежнему пытаться запустить старый сервер mysqld-max. Поэтому после
проведения модернизации подобного рода необходимо вручную удалить старый
сервер mysqld-max; это гарантирует, что mysqld_safe будет использовать новый
сервер mysqld.
Чтобы изменить настройки по умолчанию и указать явно, какой сервер должен исполь-
зоваться, для mysqldsafe потребуется задать опцию —mysqld или —mysqld-version.
Большинство опций для mysqld_safe совпадают с таковыми для mysqld (см. раздел
4.2.1).
Все опции, указанные для mysqldsafe в командной строке, передаются в mysqld. Ес-
ли понадобится использовать любые опции, которые являются специфическими для
mysqldsafe, но не поддерживаются mysqld, они не должны указываться в командной
строке. Вместо этого их следует перечислить в группе [mysqld_safe] файла опций. См.
раздел 3.3.2.
mysqld_safe считывает все опции из разделов [mysqld], [server] и [mysqld_safe] в
файлах опций. Для обратной совместимости он также читает и разделы [safejnysqld],
хотя при использовании MySQL 4.0 и выше такие разделы следует переименовывать на
[mysqld_safe].
mysqldsaf e поддерживает следующие опции:
• —basediг=луть. Путь к каталогу установки MySQL.
• —core-f ile-size=pa3Mep. Размер файла ядра, который mysqld должен иметь воз-
можность создать. Значение опции передается в ulimit -с.
• —datadi r=путь. Путь к каталогу данных.
• —defaults-extra-file=путь. Имя файла опций, который будет считываться до-
полнительно, помимо обычных файлов опций.
• —defaults-file=nyTb. Имя файла опций, который будет считываться вместо
обычных файлов опций.
• —егг-1од=путь. Старая форма опции —log-error, используемая в версиях,
предшествующих MySQL 4.O.
4.1. Сервер MySQL и сценарии запуска сервера 217

• —1ес11г=путь. Путь к каталогу, в котором установлена программа mysqld. Ис-


пользуйте данную опцию для явного указания местонахождения сервера.
• —1од-еггог=луть. Регистрирует ошибку в заданном файле. См. раздел 4.8.1.
• —mysqld=nNM_nporpaMMbi. Имя программы сервера (в каталоге ledir), которую
следует запустить.
• --mysqld-versioп=cyффикc. Данная опция подобна опции —mysqld, но для имени
программы сервера указывается только суффикс. Предполагается, что базовым
именем является mysqld. Например, при использовании --mysqld-version=max
сценарий mysqld_safe запустит программу mysqld-max из каталога l e d i r . Если
аргумент —mysqld-version не указан, mysqld_safe использует mysqld из каталога
ledir.
• —nice=приоритет. С помощью программы nice устанавливает заданный приори-
тет планирования для сервера.
• —no-defaults. He считывать никакие файлы опций.
• —open-files-limit=KcwjwecTBo. Количество файлов, которые должны быть от-
крыты mysqld. Значение опции передается в ulimit -n. Обратите внимание, что
для корректной работы данной опции потребуется запускать mysqld_safe от име-
ни привилегированного (root) пользователя.
• —pid-f Ие=путь. Путь к файлу идентификатора процесса.
• --port=HOMep_nopTa. Номер порта, который будет использоваться для прослуши-
вания TCP/IP-соединений.
• —socket=nyTb. Файл Unix-сокета, используемый для локальных соединений.
• --timezone=3OHa. Присваивает определенное значение переменной часового поя-
са TZ. По вопросам допустимых форматов для указания часовых поясов обращай-
тесь в документацию по операционной системе.
• —user={имя_пользователя \ идентификатор_пользователя}. Запускает сервер
mysqld от имени пользователя с именем имя_пользователя или числовым иденти-
фикатором идентификатор_пользователя. ("Пользователь" в данном контексте оз-
начает учетную запись для входа в систему, а не пользователя MySQL, указанного
в таблицах привилегий.)
Сценарий mysqld_saf e написан так, что позволяет нормально запускать сервер, уста-
новленный как из исходного дистрибутива MySQL, так и бинарного, несмотря на то, что
размещение сервера при каждом указанном виде установки осуществляется немного по-
разному. (См. раздел 2.1.5.) Для mysqld_safe обязательным является одно из следующих
условий:
• Сервер и базы данных могут должны быть найдены относительно каталога, из ко-
торого вызывается mysqldsafe. При использовании бинарных дистрибутивов
mysqld_safe в своем рабочем каталоге ищет папки bin и data. При использова-
нии исходных дистрибутивов mysqldsafe ищет папки libexec и var. Выполне-
ние данного условия обязательно, если mysqld_saf e запускается из каталога уста-
новки MySQL (например, для бинарного дистрибутива этим каталогом будет
/usr /local /mysql).
218 Глава 4. Администрирование баз данных

• Если сервер и базы данных не могут быть найдены относительно рабочего ката-
лога, mysqldsafe пытается найти их по абсолютным именам путей, обычно это
/usr/local/libexec и /usr/local/var. Фактическое местонахождение сервера и
базы данных определяется через значения, заданные в дистрибутиве во время его
сборки. Они будут корректными, если MySQL установлен в каталоге, указанном
во время конфигурирования.
Поскольку mysqld_safe будет пытаться найти сервер и базы данных относительно
своего собственного рабочего каталога, бинарный MySQL можно установить в любое
место, при этом запуск mysqld_safe должен осуществляться из каталога установки
MySQL:
shell> cd каталог_установки_тузд1
shell> bin/mysqld_safe &
Если не удается запустить mysqld_safe даже из каталога установки MySQL, можно
задать опции —ledir и -datadir, чтобы указать каталоги, где в вашей системе разме-
щаются сервер и базы данных.
Обычно редактировать сценарий mysqld_safe не нужно. Вместо этого конфигуриро-
вание mysqldsafe осуществляется с помощью опций командной строки или опций в
разделе [mysqld_safe] файла my.cnf. Лишь в редких случаях может понадобиться ре-
дактирование сценария mysqld_saf e для корректного запуска сервера. Однако тогда, при
будущих модернизациях версий MySQL, модифицированный сценарий mysqld_safe бу-
дет заменен новым. Чтобы избежать этого, потребуется делать копию отредактирован-
ной версии, которую при необходимости можно будет установить повторно.
В среде NetWare mysqld_safe - это загружаемый модуль NLM, который переносится
с оригинального основного сценария Unix; выполняет он следующие действия:
1. Запускает набор проверок системы и опций.
2. Запускает проверку таблиц My ISAM и ISAM.
3. Обеспечивает экранное представление сервера MySQL.
4. Запускает mysqld, осуществляет текущий мониторинг, а также перезапуск в слу-
чае ошибки.
5. Регистрирует сообщение об ошибке в mysqld в журнале имя_хоста.еи, который
находится в каталоге данных.
6. Регистрирует экранный вывод mysqld_safe в журнале имя^хоста. err, который
находится в каталоге данных.

4.1.4. Сценарий запуска сервера mysql.server


Дистрибутивы MySQL для Unix включают сценарий под названием mysql.server.
Он может применяться в системах, подобных Linux и Solaris, которые используют ката-
логи запуска в стиле System V для запуска и завершения работы системных служб. Кро-
ме того, этот же сценарий применяется компонентами запуска Mac OS Startup Item для
MySQL.
mysql.server можно найти в подкаталоге support-files каталога установки MySQL
или в исходном дереве MySQL.
При использовании RPM-пакета сервера Linux (MySQL-server-ВЕРСИЯ.грт), сценарий
mysql. server будет уже установлен в каталоге /etc/init .d с именем mysql. Устанавли-
4.1. Сервер MySQL и сценарии запуска сервера 219

вать вручную его не придется. Более подробная информация о RPM-пакетах сервера


Linux представлена в разделе 2.2.2.
Некоторые производители предлагают RPM-пакеты программ, в которых сценарий
запуска устанавливается под другим именем, таким как mysqld.
При установке MySQL из исходного дистрибутива или при использовании бинар-
ного формата, в котором автоматическая установка mysql. server не выполняется,
mysql. server можно установить вручную. Необходимые для осуществления данной
операции действия описаны в разделе 2.4.3.
mysql.server считывает опции из разделов [mysql.server] и [mysqld] файлов
опций. Для обратной совместимости он также считывает и разделы [mysql_server],
хотя в версии MySQL 4.0 и выше такие разделы должны быть переименованы в
[mysql.server].

4.1.5. Программа mysqld_multi для управления


множественными MySQL-серверами
Программа mysqldjnulti предназначена для управления несколькими процессами
mysqld, которые отвечают за соединения через различные Unix-сокеты и TCP/IP-порты.
Она может запускать и останавливать серверы или же выводить отчет об их текущем
состоянии.
Программа осуществляет поиск групп [mysqld#] в файле my.cnf (или в файле, ука-
занном в опции —conf ig-f ile). # - это любое положительное целое число. В дальней-
шем данное число будет называться номером группы опций, или GNR. Номера групп
отличают группы опций друг от друга и используются в качестве аргументов для
mysqldmulti, чтобы указать, какие серверы следует запустить, остановить, или о состоя-
нии каких из них необходимо получить отчет. Опции, перечисленные в этих группах, - те
же, что использовались бы в группе [mysqld] для запуска mysqld. (См. раздел 2.4.3.) Одна-
ко в случае с множественными серверами необходимо, чтобы каждый из них использовал
свое собственное значение для опций, таких как файл сокета Unix и номер ТСРЛР-порта.
Дополнительные сведения о том, какие опции должны быть уникальными для каждого
сервера в окружении с множественными серверами, можно найти в разделе 4.9.
Для вызова mysqldjnulti используйте следующий синтаксис:
shell> mysqldjnulti [опции] {start|stop|report} [GNR[fGNR]...]
s t a r t , stop и report обозначают операцию, которую необходимо выполнить. Ука-
занная операция может быть выполнена на одном или сразу на нескольких серверах, в
зависимости от списка номеров GNR, который следует за названием опции.
Каждое значение GNR отображает номер группы опций или диапазон таких номеров.
Значение должно представлять собой номер в конце названия группы в файле опций.
Например, значением GNR для группы [mysqldl7] является число 17. Чтобы указать
сразу несколько номеров, между первым и последним числом необходимо поставить
тире. Значение GNR 10-13 представляет группы OT[mysqldlO] до [mysqldl3]. Множест-
венные группы или блоки групп можно указывать в командной строке, разделив их за-
пятыми. В списке GNR не должно быть никаких пропусков (пробелов или символов та-
буляции); все значения после таких пропусков игнорируются.
Приведенная ниже команда запускает один сервер, используя группу опций
[mysqldl7]:
shell> mysqld__multi start 17
220 Глава 4. Администрирование баз данных

Следующая команда останавливает несколько серверов, используя группы опций


[mysql8] йот [mysqldlO] ДО [mysqldl3]:
shell> mysqldjnulti start 8,10-13
Чтобы просмотреть пример файла опций, воспользуйтесь такой командой:
shell> mysqldjnulti —example
Ниже представлен список опций, которые поддерживает mysqldjnulti.
• --config-file=HM#. Указывает имя альтернативного файла опций. Это влияет на
то, где mysqldjnulti будет искать группы опций [mysqld#]. Если данная опция
отсутствует, все опции считываются из обычного файла my.cnf. Эта опция не
влияет на то, откуда mysqldjnulti считывает свои собственные опции, которые
всегда берутся из группы [mysqldjnulti] обычного файла my. cnf.
• —example. Отображает пример файла опций.
• —help. Отображает справочную информацию и завершает работу.
• —1од=имя. Указывает имя файла журнала. Если он существует, выходные записи
добавляются в конец файла.
• —mysqladmin=HM#_nporpaMMb/. Бинарный файл mysqladmin, используемый для ос-
танова серверов.
• —туБО{Ы=имя_программы. Бинарный файл mysqld, который должен использовать-
ся. Обратите внимание, что для данной опции в качестве значения можно также
указывать mysqld_saf е. Только для этого следует убедиться, что в параметрах пе-
ременной окружения PATH присутствует каталог, в котором размещен mysqld, или
должным образом настроить mysqld_saf е.
• --no-log. Регистрировать данные в stdout, а не в системном журнале. По умол-
чанию выходные данные заносятся в системный журнал.
• —password=napcwb. Пароль учетной записи MySQL, который будет использовать-
ся при вызове mysqladmin. Обратите внимание, что значение пароля для данной
опции, в отличие от других MySQL-программ, является обязательным.
• —tcp-ip. Подключается к каждому серверу MySQL через TCP/IP-порт, а не Unix-
сокет. (При отсутствии файла сокета сервер по-прежнему может работать, но дос-
туп к нему будет возможен только через порт TCP/IP.) По умолчанию соединения
устанавливаются только с использованием файла сокета Unix. Данная опция ока-
зывает влияние на операции stop и report.
• —изег=имя_пользователя. Имя пользователя учетной записи MySQL, которое бу-
дет использоваться при вызове mysqladmin.
• —version. Отображает данные о версии и завершает работу.
Ниже представлены некоторые важные замечания по mysqldjnulti.
• Удостоверьтесь, что учетная запись MySQL, используемая для останова серверов
mysqld (с помощью программы mysqladmin) имеет одно и то же имя пользователя
и пароль для каждого сервера. Также убедитесь в наличии привилегии SHUTDOWN.
Если необходимые серверы используют много различных имен пользователей и
паролей для доступа к административным учетным записям, возможно, понадо-
бится создать учетную запись на каждом сервере с одинаковым паролем и именем
4.1. Сервер MySQL и сценарии запуска сервера 221

пользователя. Например, можно установить общую учетную запись multi_adrain,


выполнив следующие команды для каждого сервера:
shell> mysql -u root -S /tmp/mysql.sock --рпароль_гооЬ
mysql> GRANT SHUTDOWN ON *.*
-> TO 'multi^admin'e'localhost1 IDENTIFIED BY 'multipass1;
См. раздел 4.4.2. Это потребуется сделать для каждого сервера mysqld. Соответст-
вующим образом изменяйте параметры соединений при подключении к каждому
из них. Обратите внимание, хост-часть учетной записи должна разрешать соеди-
нения через multiadmin с хоста, на котором вы хотите запускать mysqldjnulti.
• Опция —pid-file чрезвычайно важна при использовании mysqld_safe для запус-
ка mysqld (например, —mysqld=mysqld_safe). Каждый mysqld должен иметь свой
собственный файл идентификатора процесса. Преимущество применения
mysqld_safe вместо mysqld состоит в том, что mysqld_safe "оберегает" процесс
mysqld и перезапустит его, если он будет остановлен вследствие сигнала, отправ-
ленного через k i l l -9, или по другим причинам, таким как ошибка сегментации.
Обратите внимание, что может потребоваться запускать сценарий mysqld_safe из
конкретного места. Это означает, что перед запуском mysqldjnulti придется со-
ответствующим образом сменить текущий каталог. В случае возникновения про-
блем при запуске внимательно просмотрите сценарий mysqld_safe. В частности,
просмотрите следующие строки:

MY_PWD=4pwd4
# Check if we are starting this relative (for the binary release)
# Проверяем,происходит ли запуск относительно каталога (для бинарных версий)
if test -d $MY_PWD/data/mysql -a -f ./share/mysql/english/errmsg.sys -a \
-x ./bin/mysqld

См. раздел 4.1.З. Тест, запускаемый указанными выше строками, должен пройти
успешно, тем не менее, проблемы не исключены.
• Файл сокета Unix и номер TCP/IP-порта должны быть разными для каждого
mysqld.
• Возможно указание опции —user для mysqld, однако тогда сценарий
mysqldjnulti необходимо запустить от имени привилегированного (root) пользо-
вателя Unix. Наличие опции в файле опций роли не играет; вы просто получите
предупреждение, если не являетесь суперпользователем и если процессы mysqld
запущены от имени вашей учетной записи Unix.
1 Внимание!
р! Убедитесь, что каталог данных полностью доступен для учетной записи Unix, через которую за-
^ пускается определенный процесс mysqld. Если вы не уверены в своих действиях, не исполь-
зуйте учетную запись r o o t в Unix.
Очень важно перед использованием m y s q l d j n u l t i убедиться в том, что вы понимаете значения
опций, передаваемых серверам mysqld, равно как в том, почему могут понадобиться отдельные
процессы mysqld. He забывайте о риске при использовании множественных серверов mysqld с
одним и тем же каталогом данных. Если вы не уверены в своих действиях, отдельные каталоги
данных в таком случае - это лучший вариант. Запуск множественных серверов с одним и тем же ката-
логом данных отнюдь не повышает производительность многопоточной системе. См. раздел 4.9.
222 Глава 4. Администрирование баз данных

Следующий пример демонстрирует, как настроить файл опций для mysqld_multi.


Первая и пятая группы [mysqld#] были намеренно исключены из примера, чтобы про-
иллюстрировать возможность наличия "прорех" в файле опций. Это обеспечивает боль-
шую гибкость. Порядок запуска или остановки программ будет зависеть от порядка, в
котором они размещаются в файле опций.
# Этот файл скорее всего должен находиться в вашем домашнем каталоге
# (~/.my.cnf) или в /etc/my.cnf
# Версия 2.1 от Яни Толонена (Jani Tolonen)

[mysqld_multi]
mysqld = /usr/local/bin/mysqld_safe
mysqladmin = /usr/local/bin/mysqladmin
user = multi_admin
password = multipass

[mysqld2]
socket = /tmp/mysql.sock2
port = 3307
pid-file = /usr/local/mysql/var2/hostname.pid2
datadir = /usr/local/mysql/var2
language = /usr/local/share/mysql/english
user = John
[mysqld3]
socket = /tmp/mysql.sock3
port = 3308
pid-file = /usr/local/mysql/var3/hostname.pid3
datadir = /usr/local/mysql/var3
language = /usr/local/share/mysql/swedish
user = monty

[mysqld4]
socket = /tmp/mysql.sock4
port = 3309
pid-file = /usr/local/mysql/var4/hostname.pid4
datadir = /usr/local/mysql/var4
language = /usr/local/share/mysql/estonia
user = tonu

[mysqld6]
socket = /tmp/mysql.sock6
port = 3311
pid-file = /usr/local/mysql/var6/hostname.pid6
datadir = /usr/local/mysql/var6
language = /usr/local/share/mysql/japanese
user = jani
См. раздел З.З.2.
4.2. Конфигурирование сервера MySQL 223

4.2. Конфигурирование сервера MySQL


В данном разделе рассматриваются следующие вопросы, касающиеся конфигуриро-
вания сервера MySQL:
• Поддерживаемые сервером опции запуска.
• Установка режима SQL для сервера.
• Системные переменные сервера.
• Переменные состояния сервера.

4.2.1. Опции командной строки mysqld


При запуске сервера mysqld можно задавать программные опции, используя любой
из методов, описанных в разделе 3.3. Обычно опции указываются в файле опций или в
командной строке. Однако в большинстве случаев желательно удостовериться, что сер-
вер использует одни и те же опции при каждом запуске. Лучший способ добиться это-
го - перечислить опции в файле опций (см. раздел 3.3.2).
mysqld считывает опции из групп [mysqld] и [server], a mysqld_safe - из групп
[mysqld], [server], [mysqld_safe] и [safejnysqld]. Сценарий mysql.server считывает
опции из групп [mysqld] и [mysql.server. Встроенный сервер MySQL обычно считыва-
ет опции из групп [server], [embedded] и [xxxxx_SERVER], где ххххх - это имя приложе-
ния, в которое встроен сервер.
mysqld принимает множество опций командной строки. Чтобы просмотреть их спи-
сок, введите mysqld —help. В версиях, предшествующих MySQL 4.1.1, опция --help
выводит полную справочную информацию. Что касается версии MySQL 4.1.1, то ото-
бражается короткое сообщение; для просмотра всего списка используйте:
mysqld —verbose —help
Ниже описаны некоторые из основных опций сервера. Дополнительные опции рас-
сматриваются в других разделах книги.
• Опции, влияющие на безопасность - см. раздел 4.3.3.
• Опции, связанные с SSL - см. раздел 4.5.7.5.
• Опции управления бинарным журналом - см. раздел 4.8.4.
• Опции, относящиеся к репликации - см. раздел 5.8.
• Опции, являющиеся специальными для My ISAM, BDB или InnoDB - см. разделы
8.1.1, 8.4.3 и 9.5.
Установить значение для системной переменной сервера также можно с использова-
нием имени переменной в качестве опции, как описывается далее в разделе.
• —help, -?. Выводит короткое справочное сообщение и завершает работу. В вер-
сиях, предшествующих MySQL 4.1.1, опция —help отображает подробное спра-
вочное сообщение, начиная с версии 4.1.1. - только его сокращенный вариант.
Чтобы просмотреть полный вариант, используйте опции —verbose и —help.
• —ansi. Использование стандартного синтаксиса SQL вместо синтаксиса MySQL.
См. раздел 1.8.3. Для более точного контроля над режимом SQL сервера вместо
--ansi используйте опцию —sql-mode.
224 Глава 4. Администрирование баз данных

• —basedi г=луть, -Ь путь. Путь к каталогу установки MySQL. Все пути обычно
определяются относительно данного пути.
• —big-tables. Разрешает работать с большими объемами результатов, сохраняя
все временные данные в файлы. Данная опция позволяет предотвратить большин-
ство ошибок типа "table full" ("таблица переполнена"), но при этом замедляет об-
работку запросов, для которых таблиц в памяти (in-memory) было бы вполне дос-
таточно. В версии MySQL 3.23.2 и выше сервер обрабатывает большие объемы
результатов автоматически, используя память для маленьких временных таблиц и,
при необходимости, переключаясь на таблицы на диске.
• —bind-address=IP. IP-адрес для связывания.
• --console. Регистрировать ошибки в s t d e r r / s t d o u t , даже если задана опция
—log-error. В Windows при использовании данной опции mysqld не будет за-
крывать экран консоли.
• —character-sets-dir=nyTb. Каталог, в котором находятся наборы символов. См.
раздел 4.7.1.
• ~chroot=nyTb. Размещает сервер mysqld в закрытом окружении во время запуска,
используя системный вызов chroot (). Данная опция рекомендуется в качестве
меры безопасности, начиная с версии MySQL 4.O. (Версия MySQL 3.23 не может
обеспечить стопроцентную изоляцию chroot ().) Обратите внимание, что приме-
нение данной опции некоторым образом ограничивает функции LOAD DATA INFILE
И SELECT...INTO OUTFILE.
• — c o r e - f i l e . Записывает файл ядра в случае отказа mysqld. В некоторых системах
для raysqld_safe также понадобится задать опцию — c o r e - f i l e - s i z e . См. раздел
4.1.3. Обратите внимание, что в определенных системах, таких как Solaris, файл
ядра получить не удастся, если используется опция —user-option.
• —datadir=nyrb, -h путь. Путь к каталогу данных.
• —debug [=опции__отладки], -# [опции_отладш]. Если MySQL сконфигурирован с
использованием --with-debug, с помощью данной опции можно получить файл
трассировки выполняемых mysqld операций. Строка опции_отладки чаще всего
выглядит приблизительно так: ' d: t : о, имя_файла'.
• —default-character-set=Ha6op_CHMBCxtfOB. Использовать набор_символов как на-
бор символов по умолчанию. См. раздел 4.7.1.
• —default-collation=coпocтaвлeниe. Использовать сопоставление как сопостав-
ление по умолчанию. Эта опция доступна, начиная с версии MySQL 4.1.1. См.
раздел 4.7.1.
• —default-storage-engine=Tnn. Данная опция является синонимом —default-
table-type. Доступна, начиная с версии MySQL 4.I.2.
• --def ault-table-type=THn. Установить для таблиц тип по умолчанию. См. главу 8.
• — delay-key-write [= OFF | ON | ALL]. Указывает, как будет использоваться оп-
ция DELAYED KEYS. При записи ключей с задержкой буферы ключей не очищаются
между записями для таблиц My ISAM. Значение OFF отключает запись ключей с за-
держкой. Значение ON активизирует запись ключей с задержкой для тех таблиц,
которые были созданы с использованием опции DELAYED KEYS. Значение ALL от-
4.2. Конфигурирование сервера MySQL 225

срочивает запись ключей для всех таблиц My ISAM. Опция доступна, начиная с
MySQL 4.0.3. См. раздел 6.5.2, а также раздел 8.1.1.
\у На заметку!
V"
%, Если установить для данной переменной значение ALL, использовать таблицы My ISAM из дру-
% гой программы (например, с другого сервера MySQL или через myisamchik), когда таблица на-
f ходится в работе, не удастся, поскольку это приведет к повреждению индекса.
• —delay-key-write-for-all-tables. Старая форма —delay-key-write=ALL, ис-
пользуемая в версиях, предшествующих MySQL 4.O.3. Начиная с версии MySQL
4.0.3, вместо нее следует применять —delay-key-write.
• --des-key-file=HM#_$awia. Считывать из данного файла ключи по умолчанию,
ИСПОЛЬЗуемые функциями DES_ENCRYPT () И DES_DESCRYPT ().
• —enable-named-pipe. Активизировать поддержку именованных каналов. Данная
опция доступна только в Windows NT/200/XP и может использоваться только с
серверами mysqld-nt и mysqld-max-nt, которые поддерживают соединения через
именованные каналы.
• —external-locking. Разрешить блокировку доступа к системе. Обратите внима-
ние, что использование данной опции в системах, где lockd не работает полно-
стью (например, в Linux), приводит к зависанию mysqld. Раньше эта опция назы-
валась —enable-locking.
|! На заметку!
\" Если данная опция используется для активизации обновления таблиц My ISAM из множественных
ft процессов MySQL, необходимо убедиться, что выполнены следующие условия:
\, Запросы, которые используют таблицы, обновляемые другим процессом, не кэшируются.
1 Для любых совместно используемых таблиц не применяются опции —delay-key-write=ALL
2 или DELAY_KEY_WRITE=1.
I' Самый простой способ достичь этого - всегда использовать — e x t e r n a l - l o c k i n g вместе с
£ —delay-key-write=OFF —query-cache-size=O.
f (По умолчанию это не выполняется, поскольку в большинстве установок полезно использовать
J;: различные комбинации указанных выше опций.)

• —exit-info[=флаги], -Т [флаги]. Битовая маска различных флагов, используе-


мая для отладки сервера mysqld. He применяйте эту опцию, если не уверены в
том, что четко понимаете, как она работает!
• —flush. После каждого SQL-оператора сбрасывать на диск все изменения. Обыч-
но MySQL делает запись всех изменений на диск только после каждого SQL-
оператора и позволяет выполнять синхронизацию данных операционной системе.
См. раздел А.4.2.
• —init-file=файл. Считывать SQL-операторы из указанного файла при запуске.
Каждый оператор должен занимать одну строку и не содержать комментарии.
• —1апдиаде=имя_языка, -L имя_языка. Выводить сообщения об ошибках клиента
на указанном языке. Опция имя_языка может быть представлена в виде названия
языка или как полный путь к каталогу, в котором находятся языковые файлы. См.
раздел 4.7.2.
226 Глава 4. Администрирование баз данных

• —log[=файл], -1 [файл]. Регистрировать соединения и запросы в указанном фай-


ле. См. раздел 4.8.2. Если имя файла не указано, MySQL будет использовать
имя_хоста.1од.
• —log-bin= [ файл]. Файл бинарного журнала. Заносить все запросы, приводящие к
изменению данных, в этот файл. Используется для резервного копирования и реп-
ликации. См. раздел 4.8.4. Если имя файла не указано, MySQL в качестве имени
будет использовать имя_хоста-Ып.
• —log-bin-index [=файл]. Индексный файл для бинарных журналов. См. раздел
4.8.4. Если имя файла не указано, MySQL в качестве имени будет использовать
имя_хоста-Ып. index.
• —log-error [=файл]. Записывать сообщения об ошибках и запуске в этот файл.
См. раздел 4.8.1. Если имя файла не указано, MySQL в качестве имени будет ис-
пользовать имя_хоста. err.
• —log-isam[=файл]. Регистрировать все изменения ISAM/MylSAM в этом файле (ис-
пользуется только во время отладки ISAM/My ISAM).
• —log-long-format. Заносить некоторую дополнительную информацию в систем-
ные журналы (журнал обновлений, бинарный журнал обновлений, журнал мед-
ленных запросов, любой журнал, который был активизирован). Например, для за-
просов регистрируются имя пользователя и временная метка. Если применяются
опции —log-slow-queries и —log-long-format, тогда запросы, не использую-
щие индексов, также будут регистрироваться в журнале медленных запросов. Об-
ратите внимание, что опция --log-long-format устарела; в версии MySQL 4.1
введена опция —log-short-format (в версии 4.1 и выше этот формат журнала ус-
танавливается по умолчанию). Также следует знать, что, начиная с версии MySQL
4.1, доступна опция —log-queries-not-using-indexes, которая заносит запросы,
не использующие индексы, в журнал медленных запросов.
• —log-queries-not-using-indexes. Если вместе с данной опцией применяется
опция —log-slow-queries, тогда запросы, не использующие индексов, также будут
регистрироваться в журнале медленных запросов. Данная опция доступна, начи-
ная с версии MySQL 4.1. См. раздел 4.8.5.
• —log-short-format. Записывать минимальное количество данных в системные
журналы (журнал обновлений, бинарный журнал обновлений, журнал медленных
запросов, любой журнал, который был активизирован). Например, в таком случае
имя пользователя и временная метка для запросов не регистрируются. Данная оп-
ция была введена в MySQL 4.1.
• —log-slow-queries [=файл]. Регистрировать в журнале все запросы, выполнение
которых, в секундах, заняло больше, чем указано в long_query_time. См. раздел
4.8.5. Обратите внимание, что количество регистрируемых по умолчанию данных
в MySQL 4.1 изменилось. Для получения более подробной информации обрати-
тесь к описанию опций —log-long-format и —log-short-format.
• --log-update[=файл]. Регистрировать обновления в файл.Я, где # - это уникаль-
ный номер, если он не был указан. См. раздел 4.8.3. Журнал регистрации обнов-
лений устарел, и в MySQL 5.0.0 отсутствует, вместо него следует использовать
бинарный журнал регистрации (—log-bin). См. раздел 4.8.4. Начиная с версии
4.2. Конфигурирование сервера MySQL 227

5.0.0, использование —log-update будет просто активизировать журнал бинар-


ных регистрации.
• —log-warnings, -W. Фиксировать предупреждения, такие как Aborted connec-
t i o n . . . ("Соединение прервано") в журнал регистрации ошибок. Активизация
данной опции рекомендуется, например, при репликации (вы получите дополни-
тельную информацию о том, что происходит, например, сообщения о сбоях в сети
и повторные соединения). Данная опция в MySQL 4.1.2 активна по умолчанию;
чтобы отключить ее, используйте --skip-log-warnings. См. раздел А.2.10. До по-
явления версии MySQL 4.0 данная опция называлась —warnings.
• — l o w - p r i o r i t y - u p d a t e s . Операции по внесению изменений в таблицы
(INSERT/DELETE/UPDATE) будут иметь более низкий приоритет, недели операции
SELECT. Это также можно сделать через {INSERT | REPLACE | DELETE | UPDATE}
LOW_PRIORITY . . . , чтобы понизить приоритет только одного запроса, или через
SET LOW_PRIORITY_UPDATES=1, чтобы изменить приоритет в одном потоке. См.
раздел 6.3.2.
• —memlock. Блокировать процесс mysqld в памяти. Данная опция работает в систе-
мах, подобных Solaris, которые поддерживают системный вызов mlockall (). Это
может оказаться полезным в случае возникновения проблемы, когда операцион-
ная система сбрасывает mysqld на диск во время подкачки. Обратите внимание,
что при использовании данной опции сервер придется запускать от имени приви-
легированного (root) пользователя, что обычно нежелательно в смысле безопас-
ности.
• —myisam-recover [-опция[, опция...]]]. Установить режим восстановления
My ISAM. Значением опции может быть любая комбинация значений DEFAULT,
BACKUP, FORCE или QUICK. Если задается сразу несколько значений, их следует
разделять запятыми. Чтобы отключить данную опцию, используйте значение
"". Если же опция —myisam-recover используется, mysqld при открытии таб-
лицы проверит, отмечена ли она как дававшая сбои, или была ли таблица за-
крыта некорректно (последняя операция возможна, только если применяется
--skip-external-locking). При таких условиях mysqld запустит проверку табли-
цы. Если таблица повреждена, mysqld попытается ее восстановить.
Следующие опции влияют на процесс восстановления:
Опция Описание
DEFAULT To же самое, что и ситуация, когда не задаются никакие значения для
—myisam-recover.
BACKUP Если во время восстановления файл данных имя_та блицы. MYD изменяется,
его резервная копия сохраняется как имя__таблицы-дата-время .ВАК.
FORCE Запускается процесс восстановления, даже если при этом будет утеряно
более одной строки из файла . MYD.
QUICK Строки в таблице при отсутствии удаленных блоков проверяться не будут.

П е р е д автоматическим восстановлением т а б л и ц ы M y S Q L добавит о б э т о м запись


в журнал регистрации о ш и б о к . Ч т о б ы исключить вмешательство пользователя в
процессы восстановления таблиц после б о л ь ш и н с т в а п р о б л е м н ы х ситуаций, е л е -
228 Глава 4. Администрирование баз данных

дует использовать опции BACKUP и FORCE. Это гарантирует запуск восстановления


таблицы, даже если некоторые из строк удалены, и при этом будет сохраняться
резервная копия старого файла данных, так чтобы всегда позже можно было про-
анализировать, что конкретно произошло.
Данная опция доступна, начиная с версии MySQL 3.23.25.
• —new. Начиная с версии 4.0.12, опция --new может использоваться, чтобы в опре-
деленных аспектах заставить сервер функционировать как сервер версии 4.1, тем
самым значительно облегчая процесс обновления версий с 4.0 до 4.1:
• TIMESTAMP возвращается в виде строки в формате ' YYYY-MM-DD HH :MM: SS'.
Эта опция помогает посмотреть на поведение ваших приложений в MySQL 4.1 без
фактической модернизации до версии 4.1.
• —pid-file=nyTb. Путь к файлу идентификатора процесса, который использует
mysqld_safe.
• —рогt=HOMep__nopTa, -P номер_порта. Номер порта, используемого при прослу-
шивании ТСРЛР-соединений.
• --old-protocol, -о. Использовать протокол 3.20 для совместимости с некоторыми
очень старыми клиентами. См. раздел 2.5.6.
• —one-thread. Использовать только один поток (для отладки в Linux). Данная оп-
ция доступна при условии, что во время сборки сервера отладка была включена.
• --open-files-limit=KOffH4ecTBO. Применяется для изменения количества файло-
вых дескрипторов, доступных для mysqld. Если данная опция не установлена или
установлена со значением 0, mysqld будет использовать это значение, чтобы заре-
зервировать файловые дескрипторы для применения с функцией setrlimit (). Ес-
ли значение равно 0, тогда mysqld будет резервировать max_connections*5 или
max_connections + table_cache*2 файлов (большее значение из них). Попытай-
тесь увеличить это число, если mysqld выдает ошибку "Too many open files"
("Слишком много открытых файлов").
• —safe-mode. Пропускает некоторые шаги оптимизации.
• —safe-show-database. С данной опцией оператор SHOW DATABASES отображает
имена только тех баз данных, для которых у пользователя имеются определенные
привилегии. В MySQL 4.0.2 эта опция устарела и не приводит к какому-либо эф-
фекту (по умолчанию она установлена), поскольку теперь существует привилегия
SHOW DATABASES, которую можно использовать, чтобы контролировать доступ к
базам данных для каждой учетной записи. См. раздел 4.4.3.
• —safe-user-create. Когда эта опция включена, пользователь не может создавать
новых пользователей с помощью оператора GRANT, если он не имеет привилегии
INSERT для таблицы mysql. user или для любого ее столбца.
• —secure-auth. Запрещает аутентификацию для учетных записей, которые имеют
старые (до версии 4.1) пароли. Данная опция доступна, начиная с версии MySQL
4.1.1.
• —skip-bdb. Отключает механизм хранения BDB. В результате экономится память
и может увеличиться скорость выполнения некоторых операций. Не используйте
данную опцию, если есть необходимость в таблицах BDB.
4.2. Конфигурирование сервера MySQL 229

• —skip-concurrent-insert. Отключает возможность одновременного выбора и


вставки данных в таблицах My ISAM. (Используйте данную опцию, только если вам
кажется, что вы нашли ошибку в работе описанной функции.)
• —skip-delay-key-write. Для всех таблиц игнорировать опцию DELAY_KEY_WRITE. На-
чиная с MySQL 4.0.3, вместо этой опции следует использовать —delay-key-write=
OFF. См. раздел 6.5.2.
• —skip-external-locking. He использовать системную блокировку. Для приме-
нения isamchik или myisamchk потребуется завершить работу сервера. См. раздел
1.2.3. В MySQL 3.23 можно воспользоваться CHECK TABLE и REPAIR TABLE для
проверки либо восстановления таблицы My ISAM. Раньше эта опция называлась
—skip-locking.
• —skip-grant-tables. При установке данной опции сервер совсем не будет ис-
пользовать систему привилегий. Это предоставляет каждому полный доступ ко
всем базам данных! (Можно сделать так, чтобы сервер снова начал использовать
таблицы привилегий, с помощью команды mysldadmin flush-privileges или
mysqladmin reload, или же оператора FLUSH PRIVILEGES.)
• —skip-host-cache. He использовать внутренний кэш имен хостов для более бы-
строго преобразования имен в IP-адреса. Вместо этого запрашивать DNS-сервер
каждый раз, когда пользователь устанавливает соединение. См. раздел 6.5.5.
• —skip-innodb. Отключает механизм хранения innoDB. Это экономит память и
может повысить скорость выполнения некоторых операций. Не используйте дан-
ную опцию, если есть необходимость в наличии таблиц InnoDB.
• —skip-is am. Отключает ISAM. В MySQL 4.1 ISAM по умолчанию блокируется, по-
этому данная опция применяется только в тех случаях, когда сервер конфигури-
ровался с поддержкой ISAM. Эта опция была появилась в MySQL 4.1.1.
• —skip-name-resolve. Во время проверки соединений клиентов не будет выпол-
няться преобразование имен хостов. Используются только IP-адреса. В случае
применения данной опции все значения в столбцах Host таблиц привилегий
должны представлять собой IP-адреса или localhost. См. раздел 6.5.5.
• --skip-networking. He прослушивать TCP/IP-соединения вообще. Взаимосвязь с
mysqld должна осуществляться через именованные каналы (Windows) или файлы
сокетов Unix (Unix). Эта опция особенно рекомендуется для систем, в которых
доступ разрешен только локальным клиентам. См. раздел 6.5.5.
• —skip-new. He использовать новые, возможно некорректные, процедуры.
• --skip-symlink. Это старая форма —skip-symbolic-links, используемая в верси-
ях, предшествующих MySQL 4.0.13.
• --symbolic-links, --skip-symbolic-links. Включает или отключает поддержку
символических ссылок. Данная опция по-разному функционирует в Windows и
Unix:
• В Windows она позволяет установить символическую связь с каталогом базы
данных за счет создания файла directory.sym, который содержит путь к дей-
ствительному каталогу. См. раздел 6.6.1.3.
230 Глава 4. Администрирование баз данных

• В Unix активизация символических ссылок означает возможность связать ин-


дексный файл My ISAM или файл данных с другим каталогом посредством опций
INDEX DIRECTORY ИЛИ DATA DIRECTORY оператора CREATE TABLE. В случае уда-
ления или переименования таблицы файлы, на которые указывают символиче-
ские ссылки, также удаляются или переименовываются. Эта опция была до-
бавлена в MySQL 4.0.13.
• —skip-safemalloc. Если MySQL конфигурировался с —with-debug=full, все
MySQL-программы проверяют показатели выхода за границы памяти при каждой
операции загрузки или освобождения памяти. Процесс проверки происходит
чрезвычайно медленно, поэтому, в отсутствие необходимости, его можно избе-
жать, применив опцию —skip-safemalloc.
• —skip-show-database. С этой опцией оператор SHOW DATABASES доступен только
пользователям, имеющим привилегию SHOW DATABASES, и будет отображать имена
всех баз данных. Без этой опции SHOW DATABASES доступен всем пользователям, но
отображает имя каждой базы данных, только если пользователь имеет привиле-
гию SHOW DATABASES или какую-нибудь другую привилегию для базы данных.
• --skip-stack-trace. Данные трассировки стека записываться не будут. Эта опция
полезна при запуске mysqld в отладчике. В некоторых системах она также необ-
ходима для получения файла ядра.
• —skip-thread-priority. Отключает использование приоритетов потока с целью
сократить время отклика.
• —socket=nyTb. В Unix данная опция определяет файл сокета Unix, который будет
использоваться для локальных соединений. По умолчанию установлено значение
/tmp/mysql.sock. В Windows эта опция задает имя канала для локальных соеди-
нений, использующих именованный канал. По умолчанию имеет значение MySQL.
• — з ц 1 - т о ( 1 е = з н а ч е н и е [, з н а ч е н и е [, значение...]]. У с т а н а в л и в а е т S Q L - р е ж и мд л я
MySQL. См. раздел 4.2.2. Эта опция появилась в версии MySQL 3.23.41.
• —temp-pool. С указанием этой опции большинство временных созданных серве-
ром файлов будет использовать минимальный набор имен, а не уникальное имя
для каждого нового файла. Опция позволяет справиться с проблемой ядра Linux,
которая проявляется при создании большого количества новых файлов с разными
именами. При старом поведении в Linux наблюдается утечка памяти, поскольку
система размещается в кэше каталогов, а не в кэше диска.
• —transaction-isolation=ypoBeHb. Устанавливает уровень изоляции транзак-
ции ПО умолчанию: READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ И
SERIALIZABLE.
• --tmpdir=nyib, -t путь. Путь к каталогу, который будет использоваться для соз-
дания временных файлов. Эта опция может пригодиться, если каталог по умолча-
нию /tmp находится в разделе диска, который слишком мал, чтобы вместить вре-
менные таблицы. Начиная с версии MySQL 4.1, эта опция принимает несколько
путей, используемых по циклическому принципу. Пути должны разделяться зна-
ком двоеточия ( V ) в Unix и точкой с запятой (';') в ОС Windows, NetWare и
OS/2. Если сервер MySQL функционирует как подчиненный сервер репликации,
не следует задавать в —tmpdir значение, указывающее на каталог в файловой
4.2. Конфигурирование сервера MySQL 231

системе, зависящей от памяти, или на каталог, который очищается при перезапус-


ке хоста сервера. Серверу необходимо, чтобы некоторые из его временных фай-
лов оставались и после перезапуска машины так, чтобы он смог реплицировать
временные таблицы или операции LOAD DATA INFILE. Если после перезапуска
сервера файлы из каталога временных файлов будут удалены, репликацию про-
вести не удастся.
• —user= {имя_пользователя | идентификатор_пользователя}, -и {имя_пользователя
I идентификатор_пользователя). Запускать сервер mysqld от имени пользователя
имя_пользователя или от имени пользователя с числовым идентификатором иден-
тификатор_пользователя. ("Пользователь" в данном контексте обозначает учет-
ную запись для входа в систему, а не пользователя MySQL, указанного в таблицах
привилегий.)
Данная опция обязательна при запуске mysqld от имени привилегированного
(root) пользователя. Сервер поменяет свой идентификатор пользователя во время
запуска, что заставит его работать от имени конкретного пользователя, а не от
имени пользователя root. См. раздел 4.3.1.
Начиная с версий MySQL 3.23.56 и 4.0.12, во избежание возможных ошибок в
системе безопасности, когда пользователь добавляет опцию —user=root в какой-
нибудь файл my.cnf (в результате чего сервер запускается как root), mysqld ис-
пользует только первую заданную опцию —user и выдает предупреждение, если
таких опций сразу несколько. Опции в /etc/my, cnf и в ка та л ог_ да иных/ my.cnf
обрабатываются до опций командной строки, поэтому рекомендуется размещать
опцию —user в /etc/my.cnf и указывать значение, отличное от root. Опция в
файле /etc/my, cnf будет найдена раньше любых других опций --user, что гаран-
тирует запуск сервера как обычного пользователя, а не как привилегированного
(root), а также выдачу предупреждения в том случае, если будет обнаружена лю-
бая другая опция —user.
• —version, -V. Отобразить данные о версии программы и завершить работу.
Можно назначить значение системной переменной сервера путем использования оп-
ции в форме —имя_переменнои= значение. Например, —key_buffer_size=32M присваива-
ет переменной key_buf f er_size значение 32 Мбайт.
Обратите внимание, что при установке значения для переменной СУБД MySQL мо-
жет автоматически корректировать его, чтобы оно не выходило за конкретные пределы,
или округлять его до наиболее близкого допустимого значения, если разрешены только
определенные значения.
Также можно устанавливать переменные с использованием синтаксиса —set-variable=
имя_переменной=значение или -0 имя_переменной=значение. Однако в версиях MySQL
4.0 и выше такой синтаксис считается устаревшим.
Подробное описание всех переменных дается в разделе 4.2.3. Раздел 6.5.2, посвящен-
ный настройке параметров сервера, включает информацию по их оптимизации.
Для функционирующего сервера значения большинства системных переменных
можно изменять с помощью оператора SET.
Чтобы ограничить максимальное значение, которое можно присвоить системной пе-
ременной с помощью оператора SET, при запуске сервера используйте опцию в виде
—maximum-имя_переменной, где и укажите необходимый максимум. Например, чтобы во
время выполнения значение query_cache_size нельзя было установить выше 32 Мбайт,
232 Глава 4. Администрирование баз данных

следует задать опцию —maximum-query_cache_size=32. Данная функция доступна, на-


чиная с версии MySQL 4.O.2.

42.2. Режим SQL сервера


Сервер MySQL может работать в разных режимах SQL и (начиная с MySQL 4.1)
применять эти режимы дифференцированно для различных клиентов. Это позволяет
приложениям настраивать работу сервера в соответствии с их требованиями.
Режимы определяют, какой SQL-синтаксис MySQL должен поддерживать, и какой
тип проверок корректности данных он будет выполнять. Это облегчает использование
MySQL в разных окружениях и вместе с другими серверами баз данных.
Установить режим SQL по умолчанию можно, запустив mysqld с опцией —sql-mode=
"режимы". Начиная с версии MySQL 4.1, режим также можно изменять и после запуска,
1
задав переменную sqljnode через оператор SET [SESSION|GLOBAL] sql_mode='режимы .
Установка переменной GLOBAL влияет на работу всех подключающихся с этого времени
клиентов. Установка переменной SESSION влияет только на текущего клиента, modes -
это список различных режимов, разделяемых запятыми (','). Извлечь текущий режим
можно с помощью оператора SELECT @@sqljnode. Значение по умолчанию - пустое (то
есть режимы не установлены).
Также оно должно быть пустым (—sql-mode=""), если вы хотите его сбросить.
В нижеследующем списке представлены поддерживаемые режимы:
• ANSI_QUOTES. Трактовать ' " ' как символ кавычек идентификатора (т.е. как кавыч-
ки ' s ' ) , а не как строковый символ кавычек. По-прежнему можно использовать ' ч '
для идентификаторов в режиме ANSI. Активизировав ANSI_QUOTES, нельзя приме-
нять двойные кавычки для строковых литералов, поскольку в этом случае они бу-
дут интерпретироваться как идентификаторы. (Новая опция в MySQL 4.O.O.)
• IGNORE_SPACE. Игнорировать пробелы между именем функции и символом '('•
Это приводит к тому, что названия всех функций будут интерпретироваться как
зарезервированные слова. В результате чтобы получить доступ к любой базе дан-
ных, столбцу или таблице, имя которой является зарезервированным словом, это
имя потребуется взять в кавычки. Например, при использовании функции USERO,
имя таблицы user в базе данных mysql и имя столбца User в этой таблице становят-
ся зарезервированными словами* поэтому они должны быть заключены в кавычки:
SELECT "User" FROM mysql."user";
(Новая опция в MySQL 4.0.0.)
• NO_AUTO_VALUE_ON_ZERO. Опция NO_AUTO_VALUE_ON_ZERO влияет на обработку
столбцов AUTO_INCREMENT. Обычно следующий порядковый номер для столбца
создается путем вставки в него значения NULL или 0. NO_AUTO_VALUE_ON_ZERO ис-
ключает проведение такой операции при использовании значения 0, то есть толь-
ко NULL будет создавать следующий порядковый номер. Такой режим может при-
годиться, если 0 сохранен в столбце AUTO_INCREMENT таблицы. (Однако рекомен-
дуемым он не является.) Например, после очистки таблицы с помощью mysqldump
и перезагрузки MySQL обычно генерирует новые порядковые числа, когда сталки-
вается со значениями 0, что в результате приводит к появлению таблицы, содержи-
мое которой отличается от исходного. Включение режима NOAUTOVALUEONZERO
перед перезагрузкой файла дампа решит эту проблему. Начиная с MySQL 4.1.1,
4.2. Конфигурирование сервера MySQL 233

mysqldump автоматически вводит операторы в файлах дампа для активизации


NO_AUTO_VALUE_ON_ZERO. (Новая опция в версии MySQL 4.O.O.)
• NO_DIR_IN_CREATE. Во время создания таблицы игнорировать все директивы INDEX
DIRECTORY и DATA DIRECTORY. Эта опция полезна на подчиненных серверах репли-
кации. (Новая опция в версии MySQL 4.0.15.)
• NO_FIELD_OPTIONS. He отображать опции MySQL для столбцов в выходных дан-
ных SHOW CREATE TABLE. Используется функцией mysqlddump в режиме переноси-
мости. (Новая опция в версии MySQL 4.1.1.)
• NO_KEY_OPTIONS. He отображать опции MySQL для индексов в выходных данных
SHOW CREATE TABLE. Используется функцией mysqlddump в режиме переносимости.
(Новая опция в версии MySQL 4.1.1.)
• NO_TABLE_OPTIONS. He отображать MySQL-опции для таблиц в выходных данных
SHOW CREATE TABLE. Используется функцией mysqlddump в режиме переносимости.
(Новая опция в версии MySQL 4.1.1.)
• NO_UNSIGNED_SUBTRACTION. В операциях вычитания не отмечать результат как
UNSIGNED, если один из операндов не имеет знака. Обратите внимание, что это
приводит к тому, что UNSIGNED BIGINT не является на 100% используемым во всех
контекстах. (Новая опция в версии MySQL 4.O.2.)
• ONLYFULLGROUPBY. Запросы, которые в части GROUP BY относятся к невыбран-
ному столбцу, учитываться не будут. (Новая опция в версии MySQL 4.O.O.)
• PIPES_AS_CONCAT. Трактовать | | как операцию конкатенации строк (как и
CONTACT ()), а не как синоним операции OR. (Новая опция в версии MySQL 4.O.O.)
• REAL_AS_FLOAT. Рассматривать REAL как синоним FLOAT, а не как синоним DOUBLE.
(Новая опция в версии MySQL 4.O.O.)
Следующие специальные режимы предлагаются как сокращенные варианты для ком-
бинаций значений режимов из предыдущего списка. Они доступны, начиная с версии
MySQL 4.1.1.
• ANSI. Эквивалентен REAL_AS_FLOAT, PIPES_AS__CONCAT, ANSI_QUOTES, IGNORE_SPACE,
ONLY_FULL_GROUP_BY. См. раздел 1.8.3.
• DB2. Эквивалентен PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS,
NO_TABLE_OPTIONS, NO_FIELD_OPTIONS.
• MAXDB. Эквивалентен PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS,
NO_TABLE_OPTIONS, NO_FIELD_OPTIONS.
• MSSQL. Эквивалентен PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS,
NO_TABLE_OPTIONS, NO_FIELD_OPTIONS.
• MYSQL323. Э к в и в а л е н т е н NO_FIELD_OPTIONS.
• MYSQL40. Эквивалентен NO_FIELD_OPTIONS.
• ORACLE. Эквивалентен PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS,
NO_TABLE_OPTIONS, NO_FIELD_OPTIONS.
• POSTGRESQL. Эквивалентен PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE,
NO KEY OPTIONS, NO TABLE OPTIONS, NO_FIELD OPTIONS.
234 Глава 4. Администрирование баз данных

4.2.3. Системные переменные сервера


Сервер поддерживает большое количество системных переменных, характеризую-
щих его конфигурацию. Все они имеют значения по умолчанию. Установить перемен-
ные можно во время запуска сервера, задав опции в командной строке или в файлах оп-
ций. Большинство из них можно установить и во время выполнения с помощью опера-
тора SET.
Начиная с версии MySQL 4.0.3, сервер mysqld поддерживает два вида переменных. Гло-
бальные переменные оказывают влияние на общую работу сервера. Сеансовые переменные
влияют на операции сервера, связанные с отдельными клиентскими соединениями.
Во время запуска сервер устанавливает все глобальные переменные в их первона-
чальные значения по умолчанию. Эти значения можно изменить с помощью опций, ука-
зываемых в файлах опций или в командной строке. После запуска сервера глобальные
переменные, которые являются динамическими, можно изменить, подключившись к
серверу и выполнив оператор SET GLOBAL имя_переменной. Чтобы изменить любую гло-
бальную переменную, необходимо иметь привилегию SUPER.
Сервер также поддерживает набор сеансовых переменных для каждого подключив-
шегося клиента. Сеансовые переменные клиента инициализируются во время соедине-
ния, используя текущие значения соответствующих глобальных переменных. Сеансовые
переменные, которые являются динамическими, клиент может изменить с помощью
оператора SET SESSION имя_переменной. Для установки сеансовой переменной специ-
альной привилегии не требуется, однако клиент может изменять только свои собствен-
ные сеансовые переменные, а не переменные какого-нибудь другого клиента.
Изменение глобальной переменной видят все клиенты, получающие к ней доступ.
Однако оно отражается на соответствующей сеансовой переменной, инициализирован-
ной из глобальной переменной, только тех клиентов, которые подключились после из-
менения. На сеансовые переменные уже подключенных клиентов (и даже тех, которые
используют оператор SET GLOBAL) это никак не повлияет.
При установке переменных с помощью опции запуска их значения могут включать
суффикс К, м или G для обозначения, соответственно, числа килобайт, мегабайт или гига-
байт. Например, следующая команда запускает сервер, размер буфера ключей которого
составляет 16 Мбайт:
mysqld —key_buffer_size=16M
В версиях, предшествующих MySQL 4.0, вместо этого используйте следующий син-
таксис:
mysqld —set-variable=key_buffer_size=16M
Регистр букв в суффиксах роли не играет: 16М и 16т полностью эквивалентны.
Для установки системных переменных во время выполнения используйте оператор
SET. В таком контексте буквы в суффиксах использовать нельзя, но значение может при-
нимать форму выражения:
mysql> SET sort_buffer_size = 10 * 1024 * 1024;
Чтобы явно указать, какая переменная устанавливается - глобальная или сеансовая -
используйте опции GLOBAL и SESSION:
mysql> SET GLOBAL sortjbuffer_size = 10 * 1024 * 1024;
mysql> SET SESSION sort_buffer_size = 10 * 1024 * 1024;
4.2. Конфигурирование сервера MySQL 235

Если ни та, ни другая опция не указываются, оператор устанавливает сеансовую пе-


ременную.
Переменные, которые можно устанавливать во время выполнения, перечислены в
разделе 4.2.3.1.2.
Чтобы ограничить максимальное значение, которое разрешается присвоить систем-
ной переменной с помощью оператора SET, при запуске сервера используйте опцию
—maximum-имя_переменной, где и укажите необходимый максимум. Например, чтобы во
время выполнения значение query_cache_size нельзя было установить выше 32 Мбайт,
задается опция —maximum-query_cache_size=32. Данная функция доступна начиная с
версии MySQL 4.O.2.
Просмотреть системные переменные и их значения можно с помощью оператора
SHOW VARIABLES. Более подробная информация представлена в разделе 4.2.3.1.
m y s q l > SHOW VARIABLES;

Variable name Value |

back log 50 |
basedir /usr/local/mysql |
bdb cache size 8388572 |
bdb home /usr/local/mysql |
bdb_log_buffer_size 32768 |
bdb logdir
bdb max lock 10000 |
bdb shared data OFF |
bdb tmpdir /tmp/ |
bdb version Sleepycat Software: ... |
I binlog cache size 32768 |
I bulk insert buffer size 8388608 |
I character_set latinl |
I character sets latinl big5 czech euc kr
| concurrent insert ON ~ |
I connect timeout 5 1
I convert character_set
I datadir /usr/local/mysql/data/
I default week format 0
I delay key write ON
I delayed insert limit 100
I delayed insert timeout 300
I delayed queue size I 1000
I flush I OFF
| flush_time 1 0
I ft boolean syntax | + -><()~*:""&|
| ft max word len I 84
| ft min word len 14
| ft query expansion limit I20
I ft stopword file I (built-in)
I have bdb YES
1 have innodb I YES
236 Глава 4. Администрирование баз данных

have_isam I YES
have openssl YES
have query cache YES
have_raid NO
have symlink DISABLED
init file
innodb additional mem pool size 1048576
1 innodb_bufferj?ool_size 8388608
I innodb data file path ibdatal:10M:autoextend
I innodb data home_dir
I innodb fast shutdown ON
I innodb file io threads 4
I innodb flush log at trx commit 1
I innodb flush method
I innodb force recovery 0
I innodb lock wait timeout 50
I innodb_log_arch_dir
I innodb log archive OFF
I innodb log buffer size 1048576
I innodb log file size 5242880
I innodb log files in group 2
I innodb_log_group_home dir ./
I innodb mirrored log groups 1
I innodb thread concurrency 8
I interactive timeout 28800
1 join buffer size 131072
I key buffer size 16773120
I key cache age threshold I 300
I key_cache_block_size 1024
I key cache division limit I 100
I language /usr/local/mysql/share/
I large_files support ON
I local infile I ON
I locked in memory I OFF
1 log I OFF
I log bin | OFF
I log_slave updates I OFF
log_slow_queries I OFF
log_update | OFF
I log warnings I OFF
I long query time 1 io
I low_priority__updates I OFF
I lower case table names 1о
I max allowed packet I 1047552
I max binlog cache size I 4294967295
I max binlog size I 1073741824
I max connect errors 1 io
I max connections I 100
max delayed threads I 20
4.2. Конфигурирование сервера MySQL 237

max error count 64


max heap table size 16777216 |
max join size 4294967295
max relay log size 0
max sort length 1024
max tmp tables 32
max user connections 0
max write lock count 4294967295
myisam max extra sort file size 268435456
myisam max sort file size 2147483647
myisam recover options force
myisam repair threads 1
myisam sort buffer size 8388608
net buffer length 16384
net read timeout 30
net retry count 10
net write timeout 60
open files limit 1024
pid file /usr/local/mysql/name.pid
port 3306
protocol version 10
query_cache_limit 1048576
query cache size 0
query cache_type ON |
read buffer size 131072
read rnd buffer size 262144
rpl recovery rank 0
server id 0
skip external_locking ON
skip networking OFF
skip show database OFF
slave net timeout 3600
slow launch time 2
socket /tmp/mysql.sock
sort buffer size 2097116
sqljnode
table cache 64
table_type MYISAM
thread cache_size 3
thread stack | 131072
timezone EEST
tmp table size I 33554432
tmpdir /tmp/:/mnt/hd2/tmp/
I tx isolation I READ-COMMITTED
I version I 4.0.4-beta
I wait timeout I 28800
238 Глава 4. Администрирование баз данных

Здесь описана большая часть системных переменных. Переменные, у которых не


указан номер версии, доступны, по меньшей мере, начиная с MySQL 3.22. Системные
переменные InnoDB перечислены в разделе 9.5.
Размеры буферов и стеков указаны в байтах, если только не задаются по-другому.
Информацию о настройке этих переменных можно найти в разделе 6.5.2.
• ansijnode. Имеет значение ON (включено), если mysqld был запущен с опцией
—ansi. См. раздел 1.8.3. Эта переменная была добавлена в MySQL 3.23.6 и уда-
лена в 3.23.41. Обратитесь к описанию —sql-mode.
• backlog. Количество ожидающих выполнения запросов на подключение, которое
может иметь MySQL. Данная переменная "вступает в игру", когда главный
MySQL-поток получает слишком много запросов на соединение за очень корот-
кое время. Тогда главному потоку необходимо некоторое время (хотя и совсем
небольшое) на то, чтобы проверить соединение и запустить новый поток. Значе-
ние back_log указывает, сколько запросов может помещаться в стек на время это-
го короткого промежутка до того, как MySQL сразу же перестанет отвечать на
новые запросы. Это значение следует увеличивать только в том случае, если
предвидится большое количество подключений за короткое время.
Другими словами, данное значение - это длина очереди прослушивания входящих
TCP/IP-соединений. Ваша операционная система устанавливает собственные ог-
раничения на размер такой очереди. В инструкции по Unix, на странице, посвя-
щенной системному вызову l i s t e n ( ) , должна содержаться более подробная ин-
формация касательно этого вопроса. Проверьте в доступной документации по ОС
максимально разрешенное для данной переменной значение. Попытка установить
значение для backlog, превышающее ограничения вашей операционной систе-
мы, не принесет никаких результатов.
• basedir. Базовый каталог установки MySQL. Данную переменную можно устано-
вить с помощью опции --basedir.
• bdb_cache_size. Размер буфера, выделяемого для индексов кэширования и строк
BDB-таблиц. Если таблицы BDB использоваться не будут, следует запускать mysqld
с опцией --skip-bdb, чтобы не тратить память на этот кэш. Переменная
bdb_cache_size была добавлена в MySQL 3.23.14.
• bdbhome. Базовый каталог для таблиц BDB. Данной переменной назначается то же
значение, что и переменной datadir. Переменная bdbhome была добавлена в
MySQL 3.23.14.
• bdb_log_buffer_size. Размер буфера, выделяемого для индексов кэширования и
строк таблиц BDB. Если таблицы BDB использоваться не будут, следует установить
значение 0 или запускать mysqld с опцией —skip-bdb, чтобы не тратить память на
этот кэш. Переменная bdb_log_buf fer_size была добавлена в MySQL 3.23.14.
• bdblogdir. Каталог, в котором BDB прописывает свои файлы журналов. Данную
переменную можно установить с помощью опции —bdb-logdir. Она была добав-
лена в MySQL 3.23.14.
• bdb_max_lock. Максимально допустимое число активных блокировок в таблице
BDB (по умолчанию - 10 000). Данное значение необходимо увеличивать, если
возникают ошибки, подобные следующей, при выполнении длительных транзак-
4.2. Конфигурирование сервера MySQL 239

ций или когда mysqld приходится проверять большое количество строк в таблице,
чтобы вычислить запрос:
bdb: Lock table is out of available locks
Got error 12 from . . .
bdb: Блокировка таблицы вышла за пределы доступных блокировок
Ошибка 12 из . . .
Переменная bdb_max_lock была добавлена в MySQL 3.23.29.
• bdb_shared_data. Имеет значение ON (включено), если используется —bdb-
shared-data. Эта переменная была добавлена в MySQL 3.23.29.
• bdbtmpdir. Значение опции --bdb-tmpdir. Эта переменная была добавлена в
MySQL 3.23.14.
• bdb_version. Версия BDB. Эта переменная была добавлена в MySQL 3.23.31.
• binlog_cache_size. Размер кэша, который будет хранить SQL-операторы для би-
нарного журнала регистрации во время транзакции. Кэш бинарного журнала вы-
деляется для каждого клиента, если сервер поддерживает любой из транзакцион-
ных механизмов хранения и, начиная с версии MySQL 4.1.2, если на сервере акти-
визирован бинарный журнал регистрации (опция —log-bin). Если большие
транзакции с множественными операторами используются часто, значение этой
переменной стоит увеличить, чтобы повысить производительность. Для настрой-
ки размера переменной b i n l o g c a c h e s i z e могут пригодиться переменные со-
стояния Binlog_cache_use и Binlog_cache_disk_use. Эта переменная появилась в
версии MySQL 3.23.29. См. раздел 4.8.4.
• bulk_insert_buffer_size. MylSAM использует специальный древовидный кэш для
ускорения групповых вставок данных для операторов INSERT.. .SELECT, INSERT...
VALUES ( . . . ) , ( . . . ) , . . . и LOAD DATA INFILE. Э т а п е р е м е н н а я о г р а н и ч и в а е т
размеры дерева кэша в байтах на поток. При установленном значении 0 такая оп-
тимизация будет отключена.
'/" Внимание!
Данный кэш используется только тогда, когда данные добавляются в непустую таблицу. Значе-
;
; ние по умолчанию составляет 8 Мбайт. Эта переменная была добавлена в MySQL 4.O.3. Раньше
'; она называлась m y i s a m _ b u l k _ i n s e r t _ t r e e _ s i z e .

• character_set. Набор символов по умолчанию. Эта переменная была добавлена в


MySQL 3.23.3, затем удалена в MySQL 4.1.1 и заменена различными переменны-
ми character_set_xxx.
• character_set_client. Набор символов для операторов, поступающих со сторо-
ны клиента. Эта переменная была добавлена в MySQL 4.1.1.
• character_set_connection. Набор символов, используемый для литералов, не
имеющих устройства для ввода символов (у некоторых функций) и для преобразо-
вания числового кода в строковый. Эта переменная была добавлена в MySQL 4.1.1.
• character_set_database. Набор символов, используемый базой данных по умол-
чанию. Сервер устанавливает эту переменную всякий раз, когда изменяется база
данных по умолчанию. Если база данных по умолчанию отсутствует, переменная
будет иметь то же значение, что и character_set_server. Эта переменная была
добавлена в MySQL 4.1.1.
240 Глава 4. Администрирование баз данных

• c h a r a c t e r s e t r e s u l t s . Набор символов, используемый для возвращаемых кли-


енту результатов запроса. Эта переменная была добавлена в MySQL 4.1.1.
• character_set_server. Набор символов по умолчанию сервера. Эта переменная
была добавлена в MySQL 4.1.1.
• character_set_system. Набор символов, используемый сервером для сохранения
идентификаторов. Всегда имеет значение utf 8. Эта переменная была добавлена в
MySQL 4.1.1.
• character_sets. Поддерживаемые наборы символов. Эта переменная была добав-
лена в MySQL 3.23.15.
• collation_connection. Сопоставление набора символов соединения. Эта пере-
менная была добавлена в MySQL 4.1.1.
• collation_database. Сопоставление, используемое базой данных по умолчанию.
Сервер устанавливает эту переменную всякий раз, когда изменяется база данных
по умолчанию. Если база данных по умолчанию отсутствует, переменная будет
иметь то же значение, что и collation_server. Эта переменная была добавлена в
MySQL 4.1.1.
• c o l l a t i o n s e r v e r . Сопоставление по умолчанию. Эта переменная была добавлена
в MySQL 4.1.1.
• concurrent_inserts. При значении ON (по умолчанию) MySQL разрешает одно-
временное использование операторов INSERT и SELECT для таблиц, не содержащих
свободных блоков внутри. Эту опцию можно отключить, запустив mysqld с опци-
ей —safe или —skip-new. Эта переменная была добавлена в MySQL 3.23.7.
• connect_timeout. Количество секунд, в течение которых сервер mysqld ожидает
пакет подключения, прежде чем ответить сообщением Bad handshake (Сбойное
квитирование).
• datadir. Каталог данных MySQL. Эту переменную можно установить с помощью
опции —datadir.
• default_week_format. Значение режима по умолчанию, используемое для функ-
ции WEEK (). Эта переменная доступна в MySQL 4.0.14.
• delay__key_write. Эта опция применяется только для таблиц MylSAM. Ниже пред-
ставлены возможные значения, которые влияют на обработку опции таблиц
DELAY_KEY_WRITE, используемую в операторах CREATE TABLE:
Опция Описание
OFF DELAY_KEY_WRITE игнорируется.
ON M y S Q L принимает значение DELAY_KEY_WRITE для операторов
CREATE TABLE. Это значение по умолчанию.
ALL Все новые открытые таблицы рассматриваются как таблицы, во время
создания которых опция DELAY_KEY_WRITE была включена.
Если DELAY_KEY_WRITE включена, это означает, что очистка буфера ключей для
таблиц с этой опцией происходит не при каждом обновлении индексов, а только
когда таблица закрывается. Скорость записи ключей в таком случае значительно
возрастает, но при использовании этой функции потребуется добавить автомати-
4.2. Конфигурирование сервера MySQL 241

ческую проверку всех таблиц MylSAM, запустив сервер с опцией —myisam-recover


(например, — myisam-recover=BACKUP, FORCE). См. разделы 4.2.1 и 8.1.1.
Обратите внимание, что —external-locking совершенно не гарантирует защиту
индексов от повреждений для таблиц, которые используют запись задержанных
ключей.
Эта переменная была добавлена в MySQL 3.23.8.
• delayed_insert_limit. После вставки задержанных строк delayed_insert_limit
обработчик INSERT DELAYED проверяет наличие незавершенных команд SELECT.
Если таковые имеются, упомянутый обработчик позволяет выполнить их, прежде
чем вставка задержанных строк будет продолжена.
• delayed_insert_timeout. Насколько долго поток обработчика INSERT DELAYED
должен ожидать операторы INSERT перед завершением работы.
• delayed_queue_size. Сколько строк может находиться в очереди во время обработ-
ки операторов INSERT DELAYED. Если очередь переполняется, все клиенты, которые
выполнили INSERT DELAYED, будут ждать, пока снова появится место в очереди.
• flush. Имеет значение ON (включено), если сервер запущен с опцией —flush. Эта
переменная была добавлена в MySQL 3.22.9.
• flush_time. При ненулевом значении все таблицы закрываются каждые
flushtime секунд, чтобы освободить ресурсы и синхронизировать измененные
данные на диск. Данная опция рекомендуется только для ОС Windows 9x или Me,
а также для ОС с минимальным количеством доступных ресурсов. Эта перемен-
ная была добавлена в MySQL 3.22.18.
• f t_boolean_syntax. Список операций, поддерживаемых при булевском полнотек-
стовом поиске, который выполняется с помощью IN BOOLEAN MODE. Эта перемен-
ная была добавлена в MySQL 4.0.1.
Значение переменной по умолчанию соответствует ' + ->< () ~*: ""& Г. Для изме-
нения значения применяются следующие правила:
• Функция операции определяется позицией в строке.
• Значение замены должно состоять из 14 символов.
• Каждый символ должен представлять собой ASCII-символ, отличный от алфа-
витно-цифрового.
• Первый или второй символ - обязательно пробел.
• Дубликаты использовать нельзя, кроме операций кавычек в позициях 11 и 12.
Эти два символа не обязательно должны быть одинаковыми, но только они
могут быть таковыми.
• Позиции 10, 13 и 14 (со значениями по умолчанию ':','&' и ' Г) резервируются
для будущих расширений.
• f t_max_word_len. Максимальная длина слова для включения в индекс FULLTEXT.
Эта переменная была добавлена в MySQL 4.O.O.
f < Внимание!
\« После изменения данной переменной индексы FULLTEXT необходимо компоновать заново. Ис-
рг пользуйте для этого REPAIR TABLE имя_таблицы QUICK.
242 Глава 4. Администрирование баз данных

• ft_min_word_len. Минимальная длина слова для включения в индекс FULLTEXT.


Эта переменная была добавлена в MySQL 4.O.O.
"!: Внимание!
;
„ После изменения данной переменной индексы FULLTEXT необходимо компоновать заново. Ис-
V пользуйте для этого REPAIR TABLE имя_таблицы QUICK.

• ft_query_expansion_limit. Количество максимально точных совпадений, кото-


рое будет использоваться для полнотекстового поиска, выполняемого с помощью
WITH QUERY EXPANSION. Эта переменная была добавлена в MySQL 4.1.1.
• f t s t o p w o r d f i l e . Файл, из которого будет считываться список стоп-слов для
полнотекстового поиска. Все слова из файла используются; комментарии на обра-
ботку не принимаются. По умолчанию встроенный список стоп-слов используется
(как определено в файле myisam/ft_static.c). Если установить эту переменную
со значением пустой строки ( ' ' ) , фильтрация стоп-слов будет отключена. Эта пе-
ременная была добавлена в MySQL 4.0.10.
;"' Внимание!
\ После изменения данной переменной индексы FULLTEXT необходимо компоновать заново. Ис-
пользуйте для этого REPAIR TABLE имя_таблицы QUICK.

• group_concat_max_len. Максимально допустимые размеры результата для функ-


ции GROUP_CONTACT (). Эта переменная была добавлена в MySQL 4.I.O.
• havebdb. Может иметь значение YES, если mysqld поддерживает таблицы BDB, и
значение DISABLED, если используется --skip-bdb. Эта переменная была добавле-
на в MySQL 3.23.30.
• haveinnodb. Может иметь значение YES, если mysqld поддерживает таблицы
InnoDB, и значение DISABLED, если используется --skip-innodb. Эта переменная
была добавлена в MySQL 3.23.37.
• haveisam. Может иметь значение YES, если mysqld поддерживает таблицы ISAM, и
значение DISABLED, если используется —skip-isam. Эта переменная была добав-
лена в MySQL 3.23.30.
• have_raid. Имеет значение YES, если mysqld поддерживает опцию RAID. Эта пере-
менная была добавлена в MySQL 3.23.30.
• haveopenssl. Имеет значение YES, если mysqld поддерживает SSL (шифрование
данных) клиент-серверного протокола. Эта переменная была добавлена в MySQL
3.23.43.
• i n i t c o n n e c t . Строка, выполняемая сервером для каждого подключающегося
клиента. Строка состоит из одного или более SQL-операторов. При указании сра-
зу нескольких операторов их разделяют точкой с запятой (';')• Например, по
умолчанию для каждого клиента включен режим автоматической фиксации тран-
закций. Глобальная переменная сервера, через которую указывалось бы отключе-
ние режима фиксации, отсутствует, но добиться такого эффекта можно с помо-
щью init_connect:
SET GLOBAL init connect='SET AUTOCOMMIT=0';
4.2. Конфигурирование сервера MySQL 243

Эта переменная также может быть установлена в командной строке или в файле
опций. Чтобы установить переменную, как было только что проиллюстрировано,
используя файл опций, добавляются такие строки:
[mysqld]
init_connect='SET AUTOCOMMIT=0'
Эта переменная была добавлена в MySQL 4.I.2.
• init_f ile. Имя файла, указанного с помощью опции —in i t - f i l e во время запус-
ка сервера. Это файл, содержащий SQL-операторы, которые сервер должен вы-
полнить при запуске. Каждый оператор должен занимать одну строку и не содер-
жать комментарии. Эта переменная была добавлена в MySQL 3.23.2.
• init_slave. Эта переменная подобна init_connect, но представляет собой стро-
ку, выполняемую подчиненным сервером каждый раз при запуске SQL-потока.
Формат строки такой же, как и у переменной init_connect. Эта переменная была
добавлена в MySQL 4.I.2.
• innodb_xxx. Системные переменные InnoDB рассматриваются в разделе 9.5.
• interactive_timeout. Количество секунд, в течение которых сервер ожидает ак-
тивности на интерактивном соединении, прежде чем закрыть его. Интерактивный
клиент определен как клиент, который использует опцию CLIENT_INTERACTIVE для
функции mysql_real_connect (). См. также описание wait_timeout.
• join_buffer_size. Размер буфера, используемого при операциях полного соеди-
нения таблиц (в которых не используются индексы). Буфер устанавливается один
раз во время каждой операции соединения двух таблиц. Увеличение этого пара-
метра с целью ускорить соединения, когда добавляются индексы, результатов не
приносит. (Как правило, лучшим способом ускорения соединения таблиц является
добавление индексов.)
• key__buffer_size. Индексные блоки для таблиц MylSAM и ISAM буферизованы и ис-
пользуются всеми потоками. key_buffer_size - это размер буфера, используемо-
го для индексных блоков. Буфер ключей еще также называют кэшем ключей.
Увеличивайте данное значение для повышения эффективности обработки индек-
сов (как для операций чтения, так и многочисленных операций записи) настолько,
насколько это можно позволить в конкретной ситуации. Использование значения
в 25% от общей памяти на машине, которая в основном работает с MySQL, встре-
чается достаточно часто. Однако если значение окажется слишком большим (на-
пример, больше 50% общей памяти), система может активизировать страничный
обмен и существенно замедлить работу. Что касается кэширования файловой сис-
темы при считывании данных, MySQL полагается на операционную систему, по-
этому необходимо оставлять место и для кэша файловой системы.
Чтобы еще больше повысить скорость во время одновременной записи большого
количества строк, используйте LOCK TABLES.
Проверить эффективность буфера ключей можно с помощью команды SHOW STATUS;
необходимо проанализировать значения переменных состояния Keyj:ead_requests,
Key_reads, Key_write_requests и Key_writes.
Соотношение Keyreads и Key_read__requests обычно должно быть меньше, чем
0.01. Соотношение Key_writes и Key__write_requests близко к 1, если в основном
244 Глава 4. Администрирование баз данных

используются операции обновления и удаления, но может быть и намного мень-


ше, если наблюдается тенденция к внесению изменений, которые влияют на
большое количество записей одновременно, или когда используется опция таблиц
DELAY_KEY_WRITE.
Долю используемого буфера ключей можно определить, применяя key_buf f e r s i z e
вместе с переменной состояния Key_blocks_used и значением размера буферного
блока. Начиная с MySQL 4.1.1, размер буферного блока доступен через сервер-
ную переменную key_cache_block_size. Доля используемого буфера следующая:
(Key_blocks_used * key_cache_block_size) / key_buffer size
До MySQL 4.1.1 блоки кэша ключей занимают 1024 байта, таким образом, доля
используемого буфера ключей будет составлять:
(Key_blocks_used * 1024) / key_buffer_size
См. раздел 6.4.6.
• key_cache_age_threshold. Это значение управляет понижением статуса буферов с
горячей подцепочки (hot sub-chain) кэша ключей до теплой подцепочки (warm
sub-chain). Чем меньше значение, тем быстрее происходит это понижение. Мини-
мальное значение - 100. Значение по умолчанию составляет 300. Эта переменная
была добавлена в MySQL 4.1.1. См. раздел 6.4.6.
• key_cache_block_size. Размер блоков в кэше ключей в байтах. Значение по умол-
чанию - 1024. Эта переменная была добавлена в MySQL 4.1.1. См. раздел 6.4.6.
• key_cache_division_limit. Разделительная точка между горячей и теплой подце-
почками буферной цепочки кэша ключей. Значение - это процент буферной це-
почки, который будет использоваться для теплой подцепочки. Допустимые зна-
чения лежат в диапазоне от 1 до 100. Значение по умолчанию - 100. Эта перемен-
ная была добавлена в MySQL 4.1.1. См. раздел 6.4.6.
• language. Язык, используемый для сообщений об ошибках.
• l a r g e f i l e s u p p o r t . Компилировался ли сервер mysqld с опциями для поддержки
больших файлов. Эта переменная была добавлена в MySQL 3.23.28.
• local_infile. Поддерживается ли LOCAL для операторов LOAD DATA INFILE. Эта
переменная была добавлена в MySQL 4.O.3.
• locked_in_memory. Заблокирован ли mysqld в памяти с помощью —memlock. Эта
переменная была добавлена в MySQL 3.23.25.
• log. Активизирована ли функция регистрации всех запросов в общем журнале за-
просов. См. раздел 4.8.2.
• log_bin. Активизирован ли бинарный журнал. Эта переменная была добавлена в
MySQL 3.23.14. См. раздел 4.8.4.
• l o g s l a v e u p d a t e s . Должны ли обновления, которые подчиненный сервер полу-
чает от главного сервера, регистрироваться в собственном бинарном журнале
подчиненного сервера. Чтобы эта функция стала возможной, на подчиненном
сервере потребуется активизировать бинарный журнал. Данная переменная была
добавлена в MySQL 3.23.17. См. раздел 5.8.
4.2. Конфигурирование сервера MySQL 245

• log_slow_queries. Должны ли регистрироваться медленные запросы. То, насколько


запрос медленный, определяется значением переменной long_query_time. Данная
переменная была добавлена в MySQL 4.O.2. См. раздел 4.8.5.
• log_update. Активизирован ли журнал обновлений. Эта переменная была добав-
лена в MySQL 3.22.18. Обратите внимание, что бинарный журнал предпочтитель-
нее журнала регистрации обновлений, который не доступен, начиная с MySQL
5.0. См. раздел 4.8.3.
• long_query_time. Если запрос занимает больше, чем указано секунд, перемен-
ная состояния Slowqueries инкрементируется. При использовании опции
—log-slow-queries запрос заносится в журнал медленных запросов. Данное зна-
чение измеряется в реальном времени, а не времени центрального процессора, по-
этому запрос ниже пороговой величины в минимально загруженной системе мо-
жет оказаться выше установленного порога на системе, которая загружена сильно.
См. раздел 4.8.5.
• low_priority_updates. Если установлено значение 1, все операторы INSERT,
UPDATE, DELETE и LOCK TABLE WRITE будут ожидать, пока на задействованной таб-
лице не останется невыполненных операций SELECT или LOCK TABLE READ. Эта
переменная раньше называлась sql_low_priority_updates. Она была добавлена в
MySQL 3.22.5.
• lower_case_table_names. Если установлено значение 1, имена таблиц сохраняют-
ся на диск с использованием символов нижнего регистра и сравнения имен таблиц
к регистру не чувствительны. Эта переменная была добавлена в MySQL 3.23.6.
Если установлено значение 2 (новая опция в версии 4.0.18), имена таблиц сохра-
няются в таком, каком они есть виде, но сравниваются в нижнем регистре. Начи-
ная с MySQL 4.0.2, эта опция также применяется и к именам баз данных, а начи-
ная с версии 4.1.1 - и к псевдонимам таблиц.
Не следует присваивать данной переменной значение 0, если MySQL запускается
в системе, которая не поддерживает имен файлов, чувствительных к регистру (та-
кой как Windows или Mac OS X). Новая опция в 4.0.18: если значение этой пере-
менной равно 0, а файловая система, в которой находится каталог данных, не со-
держит имен файлов, чувствительных к регистру, MySQL автоматически устанав-
ливает для lower_case_table_names значение 2.
• max_allowed_packet. Максимальный размер одного пакета. Первоначально буфер
сообщений имеет значение net_buf fer_length (в байтах), однако оно при необ-
ходимости может быть увеличено до max_allowedjpacket. Значение по умолча-
нию - маленькое, чтобы обеспечить фиксацию больших (возможно некоррект-
ных) пакетов. Это значение необходимо увеличить, если будут использоваться
объемные столбцы BLOB. И оно должно быть столь же большим, как и самый
большой двоичный объект данных (BLOB), с которым придется работать. Ограни-
чение по протоколу для max_allowed_packet - 16 Мбайт в версиях до MySQL 4.0
и 1 Гбайт для всех последующих версий.
• max_binlog_cache_size. Если для транзакции с множественными операторами
потребуется памяти больше, чем здесь указано, генерируется ошибка Multi-
statement transaction required more than 'max_binlog_cache_size' bytes of
storage (При выполнении транзакции с множественными операторами потребо-
246 Глава 4. Администрирование баз данных

валось больше, чем указано в ' m a x b i n l o g c a c h e s i z e ' байт для сохранения). Эта
переменная была добавлена в MySQL 3.23.29.
• maxbinlogsize. Если запись в бинарном журнале превышает данное значение,
чередовать бинарные журналы. Для данной переменной нельзя установить значе-
ние больше, чем 1 Гбайт, и меньше, чем 4096 байт. (Минимальное значение до
MySQL 4.0.14 составляет 1024 байт.) Значение по умолчанию - 1 Гбайт. Эта пе-
ременная была добавлена в MySQL 3.23.33.
Обратите внимание, если используются транзакции: транзакция записывается в
бинарный журнал регистрации как одно целое и, следовательно, никогда не рас-
пределяется по нескольким бинарным журналам. Таким образом, если выполня-
ются большие транзакции, не исключено появление бинарных журналов разме-
ром, превышающим значение max_binlog_size.
Если max_relay_log_size имеет значение 0, значение max_binlog_size будет так-
же применяться и для журналов ретрансляции. Опция max_relay_log_size была
добавлена в MySQL 4.0.14.
• max_connect_errors. Если количество прерванных соединений с хоста превышает
указанное в этой переменной число, этот компьютер будет заблокирован от даль-
нейших соединений. Его можно разблокировать с помощью оператора FLUSH
HOSTS.

• maxconnections. Разрешенное количество одновременных клиентских соедине-


ний. Увеличение этого значения увеличивает число требуемых mysqld файловых
дескрипторов. Комментарии касательно ограничений для файловых дескрипторов
можно найти в разделе 6.4.8. Также см. раздел А.2.6.
• max_delayed_threads. He запускать больше указанного здесь числа потоков для
обработки операторов INSERT DELAYED. Если попытаться вставить данные в новую
таблицу после того, как в использовании находятся все потоки, строка будет вво-
диться так, будто атрибут DELAYED указан не был. Если установить для этой пере-
менной значение 0, MySQL никогда не будет создавать поток для обработки строк
DELAYED; фактически, это полностью отключает опцию DELAYED. Эта переменная
была добавлена в MySQL 3.23.0.
• max_error_count. Максимальное число сообщений об ошибках и предупрежде-
ний, сохраняемых для отображения с помощью SHOW ERROR и SHOW WARNINGS. Эта
переменная была добавлена в MySQL 4.1.0.
• max_heap_table_size. Эта переменная устанавливает максимальный размер для
таблиц MEMORY (HEAP). Значение переменной используется, чтобы вычислять зна-
чения MAX_ROWS таблиц MEMORY. Установка данной переменной никак не отражает-
ся на любых существующих таблицах MEMORY до тех пор, пока таблица не будет
создана заново с помощью оператора, подобного CREATE TABLE или TRANCATE
TABLE, или не будет изменена с помощью ALTER TABLE. Эта переменная была до-
бавлена в MySQL 3.23.0.
• max_insert_delayed_threads. Эта переменная является синонимом
maxdelayedthreads. Она была добавлена в MySQL 4.0.19.
• max_join_size. Запрещать операторы SELECT, которым, возможно, понадобится
проверить больше, чем указано в m a x j o i n s i z e , комбинаций строк, или кото-
4.2. Конфигурирование сервера MySQL 247

рых, скорее всего, придется провести большее, чем задано в max_join_size, ко-
личество поисков на диске. Установив данное значение, вы получаете возмож-
ность фиксировать операторы SELECT, в которых ключи используются некоррект-
но, и выполнение которых может занять много времени. Применяйте его, если
пользователи склонны выполнять длительные по времени операции соединения
таблиц с пропущенными операторами WHERE или возвращающие буквально мил-
лионы строк.
Если этой переменной присвоить значение, отличное от DEFAULT, это приведет к
сбросу значения SQL_BIG__SELECTS (то есть установит его в 0). При повторной ус-
тановке SQL_BIG_SELECTS переменная max_join_size игнорируется.
Если результат запроса уже находится в кэше запросов, никакая проверка разме-
ров результата выполняться не будет, поскольку результат уже вычислен и серве-
ру ничего не стоит отправить его клиенту.
Эта переменная раньше называлась sql_max_join_size.
• max_relay_log_size. Если запись, вносимая подчиненным сервером репликации в
свой собственный журнал ретрансляции, превышает заданное здесь значение, жур-
налы ретрансляции будут чередоваться. Эта переменная позволяет ставить различ-
ные ограничения по размерам для бинарных журналов и журналов ретрансляции.
Однако, при значении 0 MySQL будет использовать max_relay_log_size как для
бинарных журналов, так и для журналов ретрансляции. Допустимые значения для
max_relay_log_size лежат в диапазоне от 4096 байт до 1 Гбайт (включительно),
или значение 0. Значением по умолчанию является 0. Эта переменная была добав-
лена в MySQL 4.0.14. См. раздел 5.3.
• max_seeks_f or_key. Ограничивает допустимое максимальное число операций по-
иска, при поиске строк по ключам. Оптимизатор MySQL предполагает, что боль-
шее, нежели указанное число операций поиска подходящих строк в таблице путем
сканирования ключей, независимо от фактического их количества, не понадобит-
ся. Если установить нижнее значение (возможно, 100), это может привести к тому,
что MySQL предпочтет сканирование ключей, а не таблиц. Эта переменная была
добавлена в MySQL 4.0.14.
• max_sort_length. Количество байт, используемых при сортировке значений BLOB
или TEXT. Используются только первые байты max_sort_length, остальные игно-
рируются.
• max_tmp_tables. Максимальное число временных таблиц, которые клиент может
оставлять открытыми одновременно. (Пока эта опция ничего не делает.)
• raax_user_connections. Максимальное число одновременных соединений, разре-
шаемых любой указанной учетной записи MySQL. Значение 0 означает отсутст-
вие ограничений. Эта переменная была добавлена в MySQL 3.23.34.
• max_write_lock_count. Размер (в байтах) указателя по умолчанию, который будет
использоваться CREATE TABLE для таблиц My ISAM, когда ни одна опция MAX_ROWS не
задана. Эта переменная не может иметь значение меньше 2 и больше 8. Значение
по умолчанию - 4. Эта переменная была добавлена в MySQL 4.I.2. См. раздел
А.2.11.
248 Глава 4. Администрирование баз данных

• myisam_max_extra_sort_f ile_size. Если временный файл, используемый для бы-


строго создания индекса My ISAM, может оказаться больше, чем кэш ключей с ука-
занным здесь размером, применяться будет метод кэширования ключей. Это
главным образом необходимо, чтобы для длинных ключей символов в больших
таблицах использовался более медленный метод кэширования ключей при созда-
нии индекса. Эта переменная была добавлена в MySQL 3.23.37.
Ц Внимание!
{§ Значение указывается в мегабайтах до версии 4.0.3 и в байтах во всех последующих версиях.
• myisam_max_sort_file_size. Максимальный размер временного файла, который
MySQL может использовать во время воссоздания индекса My ISAM (при использова-
нии REPAIR TABLE, ALTER TABLE ИЛИ LOAD DATA INFILE). ЕСЛИ размер файла больше,
чем данное значение, индекс будет создан вместо этого с помощью кэша ключей,
что намного медленнее. Эта переменная была добавлена в MySQL 3.23.37.
X' Внимание!
pi Значение указывается в мегабайтах до версии 4.0.3 и в байтах во всех последующих версиях.
• myisam_recover_options. Значение опции —myisam-recover. Эта переменная бы-
ла добавлена в MySQL 3.23.36.
• myisam_repair_threads. Если данное значение больше 1, индексы таблиц MylSAM
создаются параллельно (каждый индекс в своем потоке) во время процесса Repair
by sorting. Значение по умолчанию - 1. Следует отметить, что код многопоточ-
ного восстановления по-прежнему пребывает на стадии альфа-тестирования. Эта
переменная была добавлена в MySQL 4.0.13.
• myisam_sort_buffer_size. Буфер, выделяемый при сортировке индексов My ISAM
посредством REPAIR TABLE или при создании индексов с помощью CREATE INDEX
или ALTER INDEX. Эта переменная была добавлена в MySQL 3.23.16.
• named_pipe. В Windows указывает, поддерживает ли сервер соединения через
именованные каналы. Эта переменная была добавлена в MySQL 3.23.50.
• net_buf f er_length. Между запросами коммуникационный буфер устанавливается
с указанным здесь размером. Обычно изменять это значение нельзя, однако если
памяти не достаточно, оно устанавливается в соответствии с ожидаемыми разме-
рами операторов SQL, посылаемых клиентами. Когда операторы превышают ука-
занные здесь размеры, объем буфера автоматически увеличивается, вплоть до
max_allowed_packet байт.
• net_read_timeout. Количество секунд, в течение которых сервер должен ожидать
поступления данных через соединение, прежде чем прекратить операцию считки.
Когда сервер проводит считывание данных от клиента, net_read_timeout - это
значение блокировки по времени, отвечающее за то, когда следует завершить
задачу. Когда сервер осуществляет запись данных на стороне клиента,
net_read__timeout тоже контролирует, когда нужно прекратить операцию. См.
также slave_net_timeout. Эта переменная была добавлена в MySQL 3.23.20.
• net_retry_count. Если считывание данных через коммуникационный порт пре-
рвано, повторить попытку указанное в этой переменной число раз, прежде чем за-
вершить задачу. В среде FreeBSD значение следует устанавливать достаточно вы-
соким, поскольку сигналы внутреннего прерывания посылаются всем потокам.
Эта переменная была добавлена в MySQL 3.23.7.
4.2. Конфигурирование сервера MySQL 249

• net_write_timeout. Количество секунд ожидания, пока блок будет записан в


соединении, прежде чем операция записи будет отменена. См. также
net_reead_timeout. Эта переменная была добавлена в MySQL 3.23.20.
• open_f iles_limit. Количество файлов, которые ОС разрешает открывать mysqld.
Это реальное разрешаемое системой значение и оно может отличаться от значе-
ния, переданного mysqld в качестве опции запуска. Значение равняется 0 в систе-
мах, где MySQL не может изменить количество открытых файлов. Эта перемен-
ная была добавлена в MySQL 3.23.20.
• pid_f i l e . Путь к файлу идентификатора процесса (PID). Эту переменную можно
установить с помощью опции —pid-file. Эта переменная была добавлена в
MySQL 3.23.23.
• port. Порт, который используется сервером для прослушивания ТСРЛР-сое-
динений. Эту переменную можно установить с помощью опции —port.
• protocol_version. Версия клиент-серверного протокола, используемого сервером
MySQL. Эта переменная была добавлена в MySQL 3.23.18.
• query_alloc_block_size. Размер распределения блоков памяти, выделяемых для
создаваемых объектов во время анализа и выполнения запросов. При наличии
проблем с фрагментацией памяти увеличение данного значения может в опреде-
ленной степени помочь. Эта переменная была добавлена в MySQL 4.0.16.
• query_cache_limit. He помещать в кэш результаты, размер которых больше ука-
занного здесь. Значение по умолчанию - 1 Мбайт. Эта переменная была добавле-
на в MySQL 4.O.I.
• query_cache_min_res_unit. Минимальный размер для блоков, выделяемых кэшем
запросов. Значение по умолчанию - 4 Кбайт. Информация о настройке данной пе-
ременной содержится в разделе 4.10.3. Эта переменная доступна, начиная с вер-
сии MySQL 4.1.
• query_cache_size. Объем памяти, выделяемой для кэширования результатов за-
просов. Значение по умолчанию - 0, при котором кэш запросов отключен. Обра-
тите внимание, что указанное количество памяти будет выделено, даже если для
query_cache_type установлено значение 0. Эта переменная была добавлена в
MySQL 4.O.I.
• query_cache_type. Устанавливает тип кэша запросов. Значение GLOBAL задает тип
для всех подключающихся впоследствии клиентов. Отдельные клиенты могут ус-
тановить значение SESSION, что отразиться только на их личном использовании
кэша запросов.
Опция Описание
0 или OFF He кэшировать и не извлекать результаты. Обратите внимание, что
это не освобождает буфер кэша запросов. Для этого необходимо
установить для query_cache_size значение 0.
1 или ON Помещать в кэш все результаты запросов, кроме тех, которые начи-
наются с SELECT SQL_NO_CACHE.
2 или DEMAND Помещать в кэш результаты только запросов, начинающихся с
Select SQL_CACHE.
Эта переменная была добавлена в MySQL 4.O.3.
250 Глава 4. Администрирование баз данных

• query_cache_wlock_invalidate. Обычно когда один клиент запрашивает блоки-


ровку WRITE в таблице My ISAM, остальные клиенты не блокируются от выдачи пуб-
ликации запросов для нее, если результаты запросов представлены в кэше запро-
сов. При значении 1 этой переменной блокировка WRITE делает недействительны-
ми любые запросы в кэше запросов, относящиеся к таблице. Пока блокировка
будет действовать, всем остальным клиентам придется ждать, чтобы получить
доступ к таблице. Эта переменная была добавлена в MySQL 4.0.19.
• query_prealloc_size. Размер постоянного буфера, который используется для
синтаксического анализа и выполнения запросов. Этот буфер не освобождается
между запросами. Во время работы со сложными запросами для повышения эф-
фективности может оказаться полезным большее значение query_prealloc_size,
поскольку при этом уменьшается необходимость для сервера осуществлять рас-
пределение памяти во время выполнения запросов.
Эта переменная была добавлена в MySQL 4.0.16.
• range_alloc_block_size. Размеры блоков, которые выделяются во время оптими-
зации области. Эта переменная была добавлена в MySQL 4.0.16.
• read_buffer__size. Каждый поток, выполняющий последовательное сканирова-
ние, выделяет буфер с указанным здесь размером, для каждой сканируемой им
таблицы. При частом последовательном сканировании это значение лучше увели-
чить. Эта переменная была добавлена в MySQL 4.O.3. Раньше она называлась
record_buffer.
• readonly. Когда для подчиненного сервера репликации эта переменная установ-
лена со значением ON, он не будет получать никаких обновлений, кроме обновле-
ний из подчиненных потоков или от пользователей, имеющих привилегию SUPER.
Это может пригодиться для гарантии, что подчиненный сервер не принимает ни-
каких обновлений от клиентов. Эта переменная была добавлена в MySQL 4.0.14.
• read_rnd_buffer_size. При считывании строк по порядку после сортировки, они
считываются через указанный в этой переменной буфер, во избежание поиска на
диске. Большое значение может намного увеличить эффективность ORDER BY. Од-
нако это буфер, выделяемый для каждого клиента, поэтому не следует задавать
большое значение для глобальной переменной. Вместо этого лучше изменить се-
ансовую переменную только у тех клиентов, которым необходимо работать с
большими запросами. Эта переменная была добавлена в MySQL 4.O.3. Раньше она
называлась record_rnd_buffer.
• safe_show_database. He показывать базы данных, для доступа к которым у поль-
зователя нет привилегий. Это дает возможность повысить уровень безопасности,
если вас беспокоит то, что пользователи могут видеть, какие базы данных имеют-
ся у других пользователей. См. также skip_show_database.
Эта переменная была удалена в MySQL 4.O.5. Вместо нее для управления досту-
пом учетных записей MySQL к базам данных следует пользоваться привилегией
SHOW DATABASES.
• secure_auth. Если сервер MySQL запущен с опцией --secure-auth, он блокирует
соединения со всех учетных записей, пароли которых сохранены в старом (до
версии 4.1) формате. В этом случае значение данной переменной будет равно ON
(включено), в противном случае - OFF (выключено).
4.2. Конфигурирование сервера MySQL 251

Активизируйте данную опцию, чтобы исключить использование любых паролей в


старом формате (и, следовательно, небезопасную передачу данных через сеть).
Эта переменная была добавлена в MySQL 4.1.1.
Запустить сервер не удастся (он выдаст ошибку), если эта опция включена, а таб-
лицы привилегий хранятся в старом (до версии 4.1) формате.
Когда опция secure_auth используется клиентом, клиент отказывает в соедине-
нии с сервером, если тот для клиентской учетной записи требует пароль в старом
формате.
• server_id. Значение опции —server-id. Используется для главного и подчинен-
ного серверов репликации. Эта переменная была добавлена в MySQL 3.23.26.
• skip_external_locking. Имеет значение OFF, если mysqld использует внешнюю
блокировку. Эта переменная была добавлена в MySQL 4.O.3. Раньше называлась
skip_locking.
• skipnetworking. Имеет значение ON, если сервер разрешает только локальные (не
TCP/IP) соединения. В Unix локальные соединения используют именованные ка-
налы. В среде NetWare поддерживаются только TCP/IP-соединения, поэтому здесь
значение ON для данной переменной устанавливать не стоит. Эта переменная была
добавлена в MySQL 3.23.23.
• skip_show_database. Запрещает пользователям, не имеющим привилегии SHOW
DATABASES, применять оператор SHOW DATABASES. Это дает возможность повы-
сить уровень безопасности, если вас беспокоит то, что пользователи могут ви-
деть, какие базы данных имеются у других пользователей. См. также
safe_show_database. Эта переменная была добавлена в MySQL 3.23.24. В MySQL
4.0.2 ее результат будет также зависеть от привилегии SHOW DATABASES: при зна-
чении ON оператор SHOW DATABASES доступен только пользователям, имеющим
привилегию SHOW DATABASES, и будет отображать имена всех баз данных; при зна-
чении OFF оператор SHOW DATABASES разрешен для всех пользователей, но будет
отображать имена всех баз данных, только если у пользователя имеется привиле-
гия SHOW DATABASES или какая-нибудь привилегия для доступа к базе данных.
• slave_net_timeout. Количество секунд, в течение которых подчиненный сервер
должен ожидать поступления данных через соединение с главным сервером, пре-
жде чем прекратить считывание. Эта переменная была добавлена в MySQL
3.23.40.
• slow_launch_time. Если создание потока занимает больше, чем здесь указано се-
кунд, сервер инкрементирует значение переменной состояния Slow_launch. Эта
переменная была добавлена в MySQL 3.23.15.
• socket. В среде Unix это файл сокета Unix, используемый для локальных соеди-
нений клиента. В среде Windows это имя именованного канала, используемого
для локальных соединений клиента.
• sort_buffer_size. Для каждого потока, которому необходимо выполнить сорти-
ровку, выделяется буфер указанного через эту переменную размера. Увеличивай-
те данное значение, чтобы ускорить выполнение операций ORDER BY или GROUP BY.
См. раздел А.4.4.
252 Глава 4. Администрирование баз данных

• sqlmode. Текущий режим SQL сервера. Эта переменная была добавлена в


MySQL 3.23.41. См. раздел 4.2.2.
• storage_engine. Эта переменная является синонимом table_type. Она была до-
бавлена в MySQL 4.1.2.
• table_cache. Количество открытых таблиц для всех потоков. Увеличение этого
значения увеличивает и число требуемых mysqld файловых дескрипторов. Узнать,
есть ли необходимость в расширении кэша таблиц, поможет проверка значения
переменной состояния Opened_tables. См. раздел 4.2.4. Если значение
Opened_tables большое и FLUSH TABLES не применяется часто (что просто вынуж-
дает закрывать и открывать таблицы снова), тогда значение переменной
table_cache потребуется увеличить.
Для более подробной информации о кэше таблиц обращайтесь в раздел 6.4.8.
• table_type. Тип таблицы по умолчанию (innoDB, BDB или ISAM). Чтобы установить
тип таблицы во время запуска сервера, используйте опцию --default-table-type.
Эта переменная была добавлена в MySQL 3.23.0. См. раздел 4.2.1.
• thread_cache_size. Сколько потоков сервер должен поместить в кэш для повтор-
ного использования. После отсоединения клиента его потоки помещаются в кэш,
если только там уже не находятся потоки thread_cache_size. Запросы по потокам
удовлетворяются путем повторного использования потоков, которые по возмож-
ности берутся из кэша, и только тогда, когда кэш пуст, создается новый поток.
При большом количестве новых соединений, чтобы повысить производитель-
ность, можно увеличить значение данной переменной. (Обычно при удачной реа-
лизации потоков заметного улучшения производительности не наблюдается.)
Проанализировав разницу между переменными состояния Connections и
Threads_created (более подробная информация находится в разделе 4.2.4), можно
увидеть, насколько эффективным является кэш потоков. Эта переменная была до-
бавлена в MySQL 3.23.16.
• thread_concurrency. В среде Solaris сервер mysqld вызывает thr__setconcurrency
с этим значением. Данная функция позволяет приложениям давать системе пото-
ков подсказку о желаемом числе запускаемых одновременно потоков. Эта пере-
менная была добавлена в MySQL 3.23.7.
• threadstack. Размер стека для каждого потока. Большая часть ограничений, оп-
ределяемая тестом crash-me, зависит от этого значения. Значение по умолчанию
достаточно большое для проведения стандартной операции. См. раздел 6.1.4.
• time zone. Часовой пояс для сервера. Устанавливается из переменной окружения
TZ при запуске сервера. Часовой пояс также можно установить путем передачи
аргумента --timezone в mysqld_safe. Эта переменная была добавлена в MySQL
3.23.15. См. раздел А.4.6.
• tmp_table_size. Если временная таблица в памяти превышает указанный здесь
размер, MySQL автоматически преобразует ее в дисковую таблицу My ISAM. Уве-
личивайте значение t m p t a b l e s i z e , если часто выполняются расширенные за-
просы GROUP BY, а памяти в наличии больше, чем достаточно.
• tmpdir. Каталог, используемый для временных файлов и таблиц. Начиная с
MySQL 4.1, эту переменную можно установить в качестве списка из нескольких
4.2. Конфигурирование сервера MySQL 253

путей, которые используются по циклическому принципу. Пути отделяются двое-


точием (':') в ОС Unix и точкой с запятой (';') в ОС Windows, NetWare и OS/2.
Эта функция может применяться для распределения нагрузки между несколькими
физическими дисками. Если сервер MySQL выступает в качестве подчиненного
сервера репликации, нельзя, чтобы tmpdir указывал на каталог в зависящей от
памяти файловой системе или на каталог, который очищается при перезапуске
хоста сервера. Серверу необходимо, чтобы некоторые из его временных файлов
оставались и после перезапуска машины, так чтобы он смог реплицировать вре-
менные таблицы или операции LOAD DATA INFILE. Если после перезапуска сервера
файлы из каталога временных файлов будут утеряны, репликацию провести не
удастся.
Эта переменная была добавлена в MySQL 3.22.4.
• transaction_alloc_block_size. Размер распределения блоков памяти, выделяе-
мых для сохранения запросов, являющихся частью транзакции, которая заносится
в бинарный журнал регистрации во время фиксации. Эта переменная была добав-
лена в MySQL 4.0.16.
• transaction_prealloc_size. Размер постоянного буфера для transaction_alloc_blocks,
который не освобождается между запросами. Установив здесь достаточно боль-
шое значение, соответствующее всем запросам в стандартной транзакции, можно
избежать большинства вызовов malloc(). Эта переменная была добавлена в
MySQL 4.0.16.
• tx_isolation. Уровень локализации транзакций по умолчанию. Эта переменная
была добавлена в MySQL 4.O.3.
• version. Номер версии сервера.
• wait_timeout. Количество секунд, в течение которых сервер ожидает активности
от неинтерактивного соединения, прежде чем закрыть его.
При запуске потока сеансовое значение waittimeout инициализируется из глоба-
льного значения wait_timeout или из глобального значения interactive_timeout, в
зависимости от типа клиента (определенного опцией соединения CLIENT_INTERACTIVE
функции mysql_real_connect ()). См. также interactive_timeout.

4.2.3.1. Системные переменные


Начиная с MySQL 4.0.3, предлагается улучшенный доступ к большому количеству
системных переменных и переменных соединения. Многие переменные можно изменять
динамически во время работы сервера. Это позволяет модифицировать функционирова-
ние сервера без необходимости в его останове и перезапуске.
Сервер mysqld поддерживает два вида переменных. Глобальные переменные оказы-
вают влияние на общую работу сервера. Сеансовые переменные влияют на его функции,
связанные с соединениями со стороны отдельных клиентов.
При запуске сервера все глобальные переменные устанавливаются со значениями по
умолчанию. Эти значения можно изменять с помощью опций, указанных в файле опций
или командной строке. После запуска сервера глобальные переменные, которые являют-
ся динамическими, можно изменить, подключившись к серверу и выполнив оператор
SET GLOBAL имя_переменной. Чтобы изменить любую глобальную переменную, необхо-
димо иметь привилегию SUPER.
254 Глава 4. Администрирование баз данных

Сервер также поддерживает набор сеансовых переменных для каждого подключаю-


щегося клиента. Сеансовые переменные клиента инициализируются во время соедине-
ния на основе текущих значений соответствующих глобальных переменных. Сеансовые
переменные, которые являются динамическими, клиент может изменить с помощью
оператора SET SESSION имя_переменной. Для установки сеансовой переменной специ-
альной привилегии не требуется, однако клиент может изменять только свои собствен-
ные сеансовые переменные, а не переменные какого-нибудь другого клиента.
Изменение глобальной переменной видят все клиенты, получающие к ней доступ.
Однако оно отражается на соответствующей сеансовой переменной, инициализирован-
ной из глобальной, только тех клиентов, которые подключились после изменения. На
сеансовые переменные уже подключенных клиентов (и даже тех, которые используют
оператор SET GLOBAL) это никак не повлияет.
Глобальные и сеансовые переменные могут устанавливаться или извлекаться с помо-
щью нескольких форм синтаксиса. Следующие примеры используют sort_buffer_size
как образец имени переменной.
Чтобы установить значение переменной GLOBAL, используйте синтаксис:
mysql> SET GLOBAL sort_buffer_size=3Ha4eHne;
или:
mysql> SET @@global.sort_buffer_size=3Ha4eHne;
Чтобы установить значение переменной SESSION, используйте синтаксис:
mysql> SET SESSION sort_buffer__si ге=зяачение;
или:
mysql> SET @@session.sort_buffer_size=3Ha4eHJ<re;
или:
mysql> SET sort_buffer_size=3Ha4eHne;
Если во время установки переменной значение GLOBAL, SESSION или LOCAL не указы-
вается, по умолчанию будет установлено SESSION.
Чтобы извлечь значение переменной GLOBAL, применяйте один из следующих опера-
торов:
mysql> SELECT @@global.sort_buffer_size;
mysql> SHOW GLOBAL VARIABLES like 'sortjmffer_size';
Чтобы извлечь значение переменной SESSION, используйте один из следующих опе-
раторов:
mysql> SELECT @@sort_buffer_size;
mysql> SELECT @@session.sort_buffer_size;
mysql> SHOW SESSION VARIABLES like 'sort_buffer_size';
Здесь также LOCAL представляет собой синоним SESSION.
При извлечении переменной с помощью SELECT №имя_переменной (то есть не указы-
вается ни global., ни session., ни local.), MySQL возвращает значение SESSION, если
таковое существует, или в противном случае - значение GLOBAL.
Что касается SHOW VARIABLES, если не указать GLOBAL, SESSION или LOCAL, MySQL
возвращает значение SESSION.
4.2. Конфигурирование сервера MySQL 255

Причина такой необходимости в ключевом слове GLOBAL во время установки только


глобальных переменных (GLOBAL), но не во время их извлечения, заключается в том, что-
бы предотвратить проблемы в будущем. Если удаляется переменная SESSION с таким же
именем, клиент, имеющий привилегию SUPER, может случайно изменить переменную
GLOBAL, а не просто переменную SESSION для своего собственного соединения. Если до-
бавляется переменная SESSION с таким же именем, клиент, который пытается изменить
переменную GLOBAL, может обнаружить, что при этом изменилась только его собствен-
ная переменная SESSION.
4.2.3.1.1. Структурированные системные переменные
Структурированные системные переменные поддерживаются, начиная с MySQL
4.1.1. Структурированная переменная отличается от обычной в двух аспектах:
• Ее значение - это структура с компонентами, указывающими серверные парамет-
ры, которые считаются тесно связанными между собой.
• Может существовать несколько экземпляров данного типа структурированной
переменной. Все они имеют разные имена и ссылаются на разные ресурсы, под-
держиваемые сервером.
В настоящее время MySQL поддерживает один тип структурированных переменных.
Он определяет параметры, которые отвечают за функционирование кэша ключей.
Структурированная переменная кэша ключей имеет такие компоненты:
• key_buffer_size
• key_cache_block_size
• key_cache_division__limit
• key_cache_age_threshold
Цель данного раздела состоит в том, чтобы описать синтаксис, необходимый для об-
ращения к структурированным переменным. Переменные кэша ключей используются
для примеров синтаксиса, но детальная информация, касающаяся непосредственно того,
как функционируют кэши ключей, находится в разделе 6.4.6.
Чтобы обратиться к компоненту экземпляра структурированной переменной, можно
использовать составное имя в формате имя_экземпляра. имя_компонента. Ниже пред-
ставлены примеры:
hot_cache.key_buffer_size
hot_cache.key_cache_block_size
cold cache.key_cache_block_size
Для каждой структурированной системной переменной экземпляр с именем default
всегда предопределен. Если при обращении к компоненту структурированной перемен-
ной имя экземпляра не указывается, используется экземпляр default. Таким образом, и
default.key_buffer_size, и key_buffer_size ссылаются на одну и ту же системную
переменную.
Правила присваивания имен экземплярам и компонентам структурированных пере-
менных формулируются следующим образом:
• Для данного типа структурированной переменной каждый экземпляр должен
иметь имя, которое будет уникальным среди переменных такого типа. Однако
имена экземпляров не обязательно должны быть уникальными среди типов
структурированных переменных. Если бы не выполнялось это условие (то есть
256 Глава 4. Администрирование баз данных

если бы два разных типа структурированных переменных могли бы совместно


использовать имена-члены компонента), было бы непонятно, какую структуриро-
ванную переменную использовать для ссылок на имена-члены, не уточненные че-
рез имя экземпляра.
• Если имя экземпляра структурированной переменной недопустимо в виде иден-
тификатора без кавычек, обращайтесь к нему как к идентификатору в кавычках,
используя кавычки типа ч \ Например, hot-cache - недопустимое имя, a hot-
cache N - допустимое.
• global, session и local не являются допустимыми именами экземпляров. Это помо-
гает избежать конфликтов с обозначениями, такими как @ @ global. имя_переменной
при обращении к неструктурированным системным переменным.
На данный момент первые два правила нарушить возможности нет, поскольку един-
ственным типом структурированных переменных является тип для кэшей ключей. Эти
правила приобретут большую значимость, если в будущем будет создан какой-нибудь
новый тип структурированной переменной.
За одним исключением разрешается обращаться к компонентам структурированных
переменных, используя составные имена в любом контексте, где могут встречаться про-
стые переменные. Например, можно назначить значение структурированной переменной
с помощью опции командной строки:
shell> mysqld —hot__cache.key_buffer_size=64K
В файле опций укажите следующее:
[mysqld]
hot_cache.key_buffer_size=64K
При запуске сервера с такой опцией будет создан кэш ключей hot_cache размером
64 Кбайт, помимо кэша ключей по умолчанию размером 8 Мбайт.
Предположим, сервер запускается следующим образом:
shell> mysqld --key_buffer_size=256K \
—extra_cache.key_buffer_size=128K \
—extra_cache.key_cachejDlock_size=2048
В таком случае сервер для размера кэша ключей по умолчанию устанавливает значе-
ние 256 Кбайт. (Также можно было бы написать --default.key_buffer_size=256K).
Кроме этого, сервер создает второй кэш ключей extra_cache размером 128 Кбайт и ус-
танавливает буферы, необходимые для кэширования индексных блоков таблиц, разме-
ром 2048 байт.
Следующий пример запускает сервер с тремя разными кэшами ключей, размеры ко-
торых соотносятся как 3:1:1:
shell> mysqld —key_buffer_size=6M \
—hot_cache.keyjbuffer_size=2M \
—cold_cache.key_buffer_size=2M
Значения структурированных переменных также можно устанавливать и извлекать и
во время выполнения. Например, чтобы для кэша ключей hotcache установить размер
10 Мбайт, воспользуйтесь одним из следующих операторов:
mysql> SET GLOBAL hot_cache.keyjbuffer__size = 10*1024*1024;
mysql> SET @@global.hot_cache.keyjbuffer_size = 10*1024*1024;
4.2. Конфигурирование сервера MySQL 257

Для извлечения значения размера кэша сделайте следующее:


mysql> SELECT @@global.hot_cache.keyjbuffer_size;
Представленный ниже оператор не работает. Переменная интерпретируется не как
составное имя, а как простая строка для операции сравнения с образцом LIKE.
mysql> SHOW GLOBAL VARIABLES LIKE 'hotj:ache.keyjbuffer_size';
Это и есть то самое исключение, когда нельзя использовать имена структурирован-
ных переменных везде, где может встречаться имя простой переменной.
4.2.3.1.2. Динамические системные переменные
Начиная с MySQL 4.0.3, многие системные переменные сервера являются динамиче-
скими и могут устанавливаться во время выполнения с помощью SET GLOBAL или SET
SESSION. Также дается возможность выбирать их значения с помощью SELECT. См. раз-
дел 4.2.3.1.
В табл. 4.1 представлен полный список всех динамических системных переменных. В
последней колонке указывается, какое значение - GLOBAL или SESSION (или оба) - при-
менимо для каждой переменной.
Таблица 4.1. Динамические системные переменные
И м я переменной Тип значения Тип
autocommit булевское SESSION
big tables булевское SESSION
binlog_cache_size число GLOBAL
bulk insert buffer_size число GLOBAL | SESSION
character set client строка GLOBAL | SESSION
character set connection строка GLOBAL | SESSION
character set results строка GLOBAL | SESSION
character_set_server строка GLOBAL | SESSION
collation connection строка GLOBAL | SESSION
collation server строка GLOBAL | SESSION
concurrent insert булевское GLOBAL
connect timeout число GLOBAL
convert_character_set строка GLOBAL | SESSION
default week format число GLOBAL | SESSION
delay_key_write OFF | ON | ALL GLOBAL
delayed insert limit число GLOBAL
delayed insert timeout число GLOBAL
delayed_queue_size число GLOBAL
error count число SESSION
flush булевское GLOBAL
flush_time число GLOBAL
foreign key checks булевское SESSION
258 Глава 4. Администрирование баз данных

Продолжение табл. 4.1


Имя переменной Тип значения Тип
ft_boolean_syntax число GLOBAL
group concat max len число GLOBAL | SESSION
identity число SESSION
insert id булевское SESSION
interactive_timeout число GLOBAL | SESSION
key buffer size число GLOBAL
last_insert_id число SESSION
local__infile булевское GLOBAL
log_warnings булевское GLOBAL
long query time число GLOBAL | SESSION
low priority updates булевское GLOBAL | SESSION
max_allowed_packet число GLOBAL | SESSION
max_binlog_cache_size число GLOBAL
max_binlog size число GLOBAL
max connect errors число GLOBAL
max connections число GLOBAL
max_delayed_threads число GLOBAL
max error count число GLOBAL | SESSION
max_heap_table size число GLOBAL | SESSION
max_insert_delayed_threads число GLOBAL
max join size число GLOBAL | SESSION
max_relay_log_size число GLOBAL
max seeks for key число GLOBAL | SESSION
max sort length число GLOBAL | SESSION
max tmp tables число GLOBAL
max user connections число GLOBAL
max_write lock count число GLOBAL
myisam max extra sort file size число GLOBAL | SESSION
myisam_max_sort file size число GLOBAL | SESSION
myisam repair threads число GLOBAL | SESSION
myisam sort buffer size число GLOBAL | SESSION
net_buffer_length число GLOBAL | SESSION
net read timeout число GLOBAL | SESSION
net retry count число GLOBAL | SESSION
net write timeout число GLOBAL | SESSION
query alloc block size число GLOBAL | SESSION
query cache limit число GLOBAL
4.2. Конфигурирование сервера MySQL 259

Продолжение табл. 4.1

Имя переменной Тип значения Тип


query_cache_size число GLOBAL
query_cache_type перечисление GLOBAL | SESSION
query_cache_wlock_invalidate булевское GLOBAL | SESSION
query_prealloc_size число GLOBAL | SESSION
range_alloc_block_size число GLOBAL | SESSION
read_buffer__size число GLOBAL | SESSION
read_only число GLOBAL
read_rnd_buffer_size число GLOBAL | SESSION
rpl_recovery_rank число GLOBAL
safe_show_database булевское GLOBAL
server_id число GLOBAL
slave_compressed_protocol булевское GLOBAL
slave_net_timeout число GLOBAL
slow_launch__time число GLOBAL
sort__buffer_size число GLOBAL | SESSION
sql_auto_is_null булевское SESSION
sql_big_selects булевское SESSION
sql_big_tables булевское SESSION
sql_buffer_result булевское SESSION
sql_log_bin булевское SESSION
sql_log_off булевское SESSION
sql_log_update булевское SESSION
sql_low_priority__updates булевское GLOBAL | SESSION
sql_max_join_size число GLOBAL I SESSION
sql quote_show_create булевское SESSION
sql_safe_updates булевское SESSION
sql_select_limit число SESSION
sql_slave_skip_counter число GLOBAL
sql_warnings булевское SESSION
storage_engine перечисление GLOBAL | SESSION
table_cache число GLOBAL
table_type перечисление GLOBAL | SESSION
thread_cache_size число GLOBAL
time stamp булевское SESSION
tmp_table_size перечисление GLOBAL I SESSION
transaction_alloc_block_size число GLOBAL | SESSION
transaction_prealloc_size число GLOBAL | SESSION
260 Глава 4. Администрирование баз данных

Окончание табл. 4.1

Имя переменной Тип значения Тип


tx_isolation перечисление GLOBAL | SESSION
unique_checks булевское SESSION
wait_timeout число GLOBAL | SESSION
warning_count число SESSION

Переменные с типом "строка", принимают строковое значение. Переменные с ти-


пом с типом "число" принимают числовое значение. Значения переменных с типом
"булевское" можно установить как 0, 1, ON или OFF. Переменным с типом "перечисле-
ние" обычно следует присваивать одно из доступных для переменной значений; также
им можно присваивать число, соответствующее желаемому значению перечисления.
Для системных переменных со перечислимым типом первое такое значение соответст-
вует 0, в отличие от столбцов ENUM, для которых первое значение перечисления соот-
ветствует 1.

42.4 Переменные состояния сервера


Сервер поддерживает большое количество переменных состояния, предоставляющих
данные о его функционировании. Просмотреть эти переменные и их значения можно с
помощью оператора SHOW STATUS:
mysql> SHOW STATUS;

I Variable name Value |

I Aborted clients 0
I Aborted connects 0 1
I Bytes_received 155372598 |
I Bytes_sent 1176560426 |
I Connections 30023 |
I Created tmp disk tables 0 1
I Created tmp files 60 |
I Created tmp tables 8340 |
I Delayed errors 0 1
I Delayed insert threads 0 1
I Delayed writes 0 1
I Flush commands 1 |
I Handler__delete 462604 |
I Handler read first 105881 |
I Handler_read key 27820558
I Handler read next 390681754
I Handler read prev I 6022500
Handler_read rnd- 30546748
Handler read rnd next I 246216530
Handler update I 16945404
Handler write I 60356676
Key blocks used | 14955
I Key_read__requests I 96854827
4.2. Конфигурирование сервера MySQL 261

Key_reads 162040
Key_write_requests 7589728
Key_writes 3813196
Max_used_connections 0
Not_flushed_delayed_rows 0
Not_flushed_key_blocks 0
Open_files 2
Open_streams 0
Open_tables 1
Opened_tables 44600
Qcache_free_blocks 36
Qcache_free_memory 138488
Qcache_hits 79570
Qcache_inserts 27087
Qcache_lowmem_prunes 3114
Qcache_not_cached 22989
Qcache_queries_in_cache 415
Qcache_total_blocks 912
Questions 2026873
Select_full_join 0
Select_full_range_j oin 0
Select_range 99646
Select_range_check 0
Select_scan 30802
Slave_open_temp_tables 0
Slave_running OFF
Slow_launch_threads 0
Slow_queries 0
Sort_merge_passes 30
Sort_range 500
Sort_rows 30296250
Sort_scan 4650
Table_locks_immediate 1920382
Table_locks_waited 0
Threads_cached 0
Threads_connected 1
Threads_created 30022
Threads_running 1
Uptime 80380

Большинству переменных состояния с помощью оператора STATUS присваивается


значение 0.
То, что означают переменные состояния, описано ниже. Переменные счетчика опера-
торов Сот_ххх появились, начиная с версии MySQL 3.23.47. Переменные кэша запросов
Qcache_xxx были добавлены, начиная с MySQL 4.O.I. Все остальные переменные, для ко-
торых не указан номер версии, доступны, по крайней мере, начиная с версии MySQL 3.22.
• Aborted_clients. Количество соединений, прерванных по причине отключения
клиента без корректного закрытия соединения. См. раздел А.2.10.
• Aborted_connects. Количество неудачных попыток подключения к серверу
MySQL. См. раздел А.2.10.
262 Глава 4. Администрирование баз данных

• Binlog__cache_use. Количество транзакций, использовавших временный кэш би-


нарного журнала. Эта переменная была добавлена в MySQL 4.I.2.
• Binlog_cache__diskjjse. Количество транзакций, использовавших временный кэш
бинарного журнала, но превысивших значение binlog_cache_size и создавших
временный файл для сохранения операторов из транзакций. Эта переменная была
добавлена в MySQL 4.1.2.
• Bytesreceived. Количество байт, полученных от всех клиентов. Эта переменная
была добавлена в версии MySQL 3.23.7.
• Bytes_sent. Количество байт, отправленных всем клиентам. Эта переменная была
добавлена в версии MySQL 3.23.7.
• Comxxx. Количество раз, которое выполнялся каждый оператор ххх. Для каждого
типа оператора существует только одна переменная состояния. Например,
Comdelete и Cominsert подсчитывают количество выполнений операторов
DELETE И INSERT.

• Connections. Количество попыток (удачных и неудачных) подключения к серверу


MySQL.
• Created_tmp_disk_tables. Количество временных таблиц на диске, созданных
сервером автоматически во время выполнения операторов. Эта переменная была
добавлена в MySQL 3.23.24.
• Created_tmp_f i l e s . Количество временных файлов, созданных mysqld. Эта пере-
менная была добавлена в MySQL 3.23.28.
• Created_tmp_tables. Количество временных таблиц в памяти, созданных серве-
ром автоматически во время выполнения операторов. При большом значении
Created_tmp_disk_tables может понадобиться увеличить значение tmp_table_size,
чтобы временные таблицы зависели от памяти, а не от диска.
• Delayed_errors. Количество записанных при помощи INSERT DELAYED строк, в ко-
торых произошли какие-либо ошибки (возможно, d u p l i c a t e key).
• Delayed_insert_threads. Количество используемых потоков обработчика INSERT
DELAYED.
• Delayed__writes. Количество записанных строк INSERT DELAYED.
• Flushcommands. Количество выполненных операторов FLUSH.
• Handlercommit. Количество внутренних операторов COMMIT. Эта переменная была
добавлена в MySQL 4.O.2.
• H a n d l e r d e l e t e . Количество раз, которое строка удалялась из таблицы.
• H a n d l e r _ r e a d _ f i r s t . Количество раз, которое первая запись считывалась из ин-
декса. Если это значение высокое, то предполагается, что сервер очень часто осу-
ществляет полное индексное сканирование, например, SELECT c o l l FROM foo,
предполагая, что столбец c o l l проиндексирован.
• Handler_read__key. Количество запросов на чтение строки по ключу. Если данное
значение высокое, это хороший показатель того, что все ваши запросы и таблицы
корректно проиндексированы.
4.2. Конфигурирование сервера MySQL 263

• Handle r r e a d n e x t . Количество запросов на чтение следующей строки в порядке


расположения ключей. Это значение инкрементируется, если запрашивается ин-
дексный столбец с ограничениями по диапазону или если проводится индексное
сканирование.
• Handler_read_prev. Количество запросов на чтение предыдущей строки в порядке
расположения ключей. Данный метод считывания в основном используется для
оптимизации ORDER BY... DESC. Эта переменная была добавлена в MySQL 3.23.6.
• Handlerreadrnd. Количество запросов на чтение строки, основанных на фикси-
рованной позиции. Значение будет высоким, если выполняется много запросов,
требующих сортировки результатов. Возможно, у вас слишком много запросов,
для выполнения которых MySQL приходится сканировать целые таблицы, или
имеются соединения, которые некорректно используют ключи.
• Handler_read_rnd_next. Количество запросов на чтение следующей строки в файле
данных. Данное значение будет высоким, если сканирование таблиц проводится
часто. В целом это означает, что таблицы не проиндексированы надлежащим об-
разом или что запросы не используют преимущества имеющихся индексов.
• Handler_rollback. Количество внутренних операторов ROLLBACK.
• Handlerupdate. Количество запросов на обновление строки в таблице.
• Handlerwrite. Количество запросов на вставку строки в таблицу.
• Key_blocks_used. Количество используемых блоков в кэше ключей. Данное зна-
чение можно применять, чтобы определить, какой процент от объема кэша клю-
чей используется; см. описание переменной key_buf f eresize в разделе 4.2.3.
• Key_read_requests. Количество запросов на чтение блока ключей из кэша.
• Key_reads. Количество физических считываний блока ключей с диска. Если зна-
чение Key_reads слишком большое, тогда значение key_buffer_size, возможно,
слишком маленькое. Коэффициент неудач при обращениях к кэш-памяти можно
вычислить через Key_reads/Key_read_requests.
• Key_write_requests. Количество запросов на запись блока ключей в кэш.
• Key_writes. Количество физических записей блока ключей на диск.
• Max_used_connections. Максимальное количество соединений, используемых од-
новременно с момента запуска сервера.
• Not_flushed_delayed_rows. Количество строк, ожидающих записи в очередь
INSERT DELAY.
• Not_f lushed_key_blocks. Количество блоков ключей в кэше ключей, которые бы-
ли изменены, но пока не записаны на диск.
• Open_f iles. Количество открытых файлов.
• Openst reams. Количество открытых потоков (в основном используется для реги-
страции в журнале).
• Open_tables. Количество открытых таблиц.
• Opened_tables. Количество открывавшихся таблиц. Если значение Opened_tables
большое, тогда значение table_cache, возможно, слишком маленькое.
• Qcachef reeblocks. Количество свободных блоков памяти в кэше запросов.
264 Глава 4. Администрирование баз данных

• Qcache_f reejnemory. Объем свободной для кэша запросов памяти.


• Qcache_hits. Количество удачных обращений в кэш.
• Qcache_inserts. Количество добавленных в кэш запросов.
• Qcache_lowmem_prunes. Количество запросов, удаленных из кэша по причине не-
достаточного объема памяти.
• Qcache_not_cached. Количество запросов, не помещенных в кэш (либо потому что
они не подлежат помещению в кэш, либо из-за значения query_cache_type).
• Qcache_queries_in_cache. Количество записанных в кэш запросов.
• Qcache_total_blocks. Общее количество блоков в кэше запросов.
• Questions. Количество отправленных на сервер запросов.
• Rpl_status. Состояние отказоустойчивой репликации (пока не реализовано).
• Select_full_join. Количество соединений (таблиц), в которых индексы не ис-
пользуются. Если данное значение не равно 0, следует тщательно проверить ин-
дексы ваших таблиц. Эта переменная была добавлена в MySQL 3.23.25.
• Select_full_range_join. Количество соединений, для которых использовался
поиск по диапазону в справочной таблице. Эта переменная была добавлена в
MySQL 3.23.25.
• Select_range. Количество соединений, для которых использовались диапазоны в
первой таблице. (Обычно это значение не критично, даже если оно велико.) Эта
переменная была добавлена в MySQL 3.23.25.
• Select_range_check. Количество соединений без ключей, в которых использова-
ние ключей проверяется после каждой строки. (Если данное значение не равно О,
внимательно проверьте индексы ваших таблиц.) Эта переменная была добавлена в
MySQL 3.23.25.
• Selectscan. Количество соединений, для которых проводилось полное сканиро-
вание первой таблицы. Эта переменная была добавлена в MySQL 3.23.25.
• Slave_open_temp_tables. Количество временных таблиц, открытых на данный
момент SQL-потоком подчиненного сервера. Эта переменная была добавлена в
MySQL 3.23.29.
• Slave_running. Имеет значение ON, если это подчиненный сервер, подключенный
к главному серверу. Эта переменная была добавлена в MySQL 3.23.16.
• Slow_launch_threads. Количество потоков, создание которых заняло больше, чем
указано в slow_launch_time, секунд. Эта переменная была добавлена в MySQL
3.23.15.
• Slow_queries. Количество запросов, занявших больше, чем указано в
long_query_time, секунд. См. раздел 4.8.5.
• Sort_merge_passes. Количество проходов слияния, выполненных алгоритмом
сортировки. Если данное значение велико, необходимо увеличить значение сис-
темной переменной sort_buffer_size. Эта переменная была добавлена в MySQL
3.23.28.
• Sortrange. Количество сортировок, выполненных с использованием диапазонов.
Эта переменная была добавлена в MySQL 3.23.25.
4.3. Общие проблемы безопасности 265

• Sortrows. Количество отсортированных строк. Эта переменная была добавлена в


MySQL 3.23.25.
• Ssl__xxx. Переменные, используемые для SSL-соединений. Эти переменные были
добавлены в MySQL 4.O.O.
• Tablelocksimmediate. Количество раз, когда блокировка таблицы осуществля-
лась немедленно. Эта переменная была добавлена, начиная с версии MySQL
3.23.33.
• Table_locks_waited. Количество раз, когда немедленная блокировка таблицы бы-
ла невозможна, и требовалось время на ожидание. Если данное значение велико, и
имеются проблемы с производительностью, сначала необходимо оптимизировать
запросы, а затем либо провести разбивку таблицы или таблиц, либо прибегнуть к
репликации. Эта переменная появилась, начиная с версии MySQL 3.23.33.
• Threads_cached. Количество потоков в кэше потоков. Эта переменная была до-
бавлена в MySQL 3.23.17.
• Threads_connected. Количество открытых на данный момент соединений.
• Threads_created. Количество потоков, созданных для управления соединениями.
Если значение Threads_created велико, может понадобиться увеличить значение
thread__cache_size. Коэффициент удачных обращений в кэш можно вычислить
через Threads_created/Connections. Эта переменная была добавлена в MySQL
3.23.31.
• Threads_running. Количество потоков, не находящихся в режиме ожидания.
• Uptime. Время работоспособного состояния сервера в секундах.

4.3. Общие проблемы безопасности


В данном разделе описан ряд общих проблем, связанных с безопасностью, о которых
следует знать, а также то, что можно сделать, чтобы еще больше защитить вашу систему
MySQL от хакеров или недопустимой эксплуатации. Информация, касающаяся непо-
средственно системы управления доступом, которую MySQL использует для настройки
учетных записей и проверки прав доступа к базам данных, находится в разделе 4.4.

4.3.1. Общие принципы, касающиеся


безопасности системы
Все, кто используют MySQL на компьютере, подключенном к Internet, должны про-
читать этот раздел, дабы избежать наиболее распространенных ошибок, связанных с
безопасностью системы.
При обсуждении вопросов безопасности акцент делается на необходимости в абсо-
лютной защите хоста сервера (а не только сервера MySQL) от всевозможных атак любо-
го рода: несанкционированного перехвата данных, изменения и считывания информации
или отказа в обслуживании. Здесь охвачены далеко не все аспекты, касающиеся работо-
способности и отказоустойчивости сервера.
В MySQL для всех соединений, запросов и других операций, которые пользователь
может пытаться выполнить, используется система безопасности, основанная на списках
контроля доступа (Access Control List - ACL). Она также включает поддержку SSL-
266 Глава 4. Администрирование баз данных

соединений между клиентами и серверами MySQL. Многие обсуждаемые в данном раз-


деле принципы не являются характерными только для MySQL; основные общие понятия
применимы почти ко всем приложениям.
Работая с MySQL, по возможности руководствуйтесь следующими принципами:
• Никогда и никому (кроме привилегированных (root) учетных записей
MySQL) не предоставляйте доступ к таблице user в базе данных mysql! Это
критически важно. Зашифрованный пароль - это реальный пароль в MySQL. Лю-
бой, кто знает указанный в таблице user пароль и имеет доступ к хосту, указан-
ному для данной учетной записи, легко сможет войти в систему в качестве
пользователя.
• Изучите систему привилегий доступа MySQL. Операторы GRANT и REVOKE исполь-
зуются для управления доступом к MySQL. He предоставляйте привилегий боль-
ше, чем необходимо. И никогда не предоставляйте их всем хостам.
Ниже представлены шаги по проверке.
• Попробуйте выполнить оператор mysql -u root. Если при этом удастся успеш-
но подключиться к серверу без приглашения ввести пароль, значит у вас про-
блемы. То есть любой сможет подсоединяться к вашему серверу MySQL как
привилегированный (root) пользователь, обладающий всеми привилегиями!
Еще раз просмотрите инструкции по установке, обращая особое внимание на
информацию, касающуюся установки пароля для root. См. раздел 2.4.5.
• Используйте оператор SHOW GRANTS, чтобы проверить, кто и к чему имеет дос-
туп. Затем с помощью оператора REVOKE удалите ненужные привилегии.
• Не храните в своей базе данных незашифрованных паролей. При дискредитации
вашего компьютера злоумышленник может получить список всех паролей и вос-
пользоваться ими. Поэтому лучше применяйте MD5(), SHAH) или какую-нибудь
другую одностороннюю хеш-функцию.
• Не выбирайте для паролей слова из словаря. Существуют специальные програм-
мы для взлома таких паролей. Даже пароли наподобие "xfish98" считаются очень
плохими. Намного лучше будет пароль "duag98", который содержит то же слово
"fish", но напечатан буквами, расположенными слева от них на одну букву на
стандартной клавиатуре QWERTY. Другой метод предполагает применение паро-
лей типа "Mhall", составляемых из первых букв каждого слова в предложении; в
данном случае это предложение - "Mary had a little lamb". Такой пароль легко за-
помнить и легко вводить, но трудно разгадать тому, кто его не знает.
• Не пожалейте средств на брандмауэр. Это позволит защититься, по крайней мере,
от 50% всякого рода уязвимых мест в любом программном обеспечении. Разме-
щайте MySQL за брандмауэром или в демилитаризованной зоне (DMZ).
Ниже представлены шаги по проверке.
• Попробуйте провести сканирование портов из Internet с помощью соответст-
вующих инструментальных средств, таких как nmap. По умолчанию MySQL
использует порт 3306. Этот порт с ненадежных хостов не должен быть досту-
пен. Другой простой способ проверить, открыт или нет ваш MySQL-порт - с
какой-нибудь удаленной машины попытаться выполнить следующую команду,
где хост_сервера - имя хоста, на котором работает ваш сервер MySQL:
shell> telnet хост_сервера 3306
4.3. Общие проблемы безопасности 267

Если соединение установить удается, и вы получаете какие-то посторонние


символы, значит, порт открыт и его следует закрыть на брандмауэре или мар-
шрутизаторе, пока не появится действительно веская причина оставить этот
порт открытым. Если же telnet просто зависнет, или при попытке подклю-
читься будет получен отказ, значит, все в порядке: порт заблокирован.
• Не доверяйте никаким данным, которые вводят пользователи приложений. Они
могут попытаться обхитрить ваш код посредством ввода последовательностей
специальных или управляющих символов в Web-формах, полях URL-адресов или
в любых созданных вами приложениях. Убедитесь, что защита приложения оста-
ется надежной, даже когда пользователь вводить что-нибудь типа "; DROP
DATABASE mysql;". Хоть это и крайний случай, однако серьезные бреши в системе
безопасности и потеря данных нередко становятся результатом действий хакеров,
использующих подобные приемы, когда вы к ним не готовы.
Самая типичная ошибка - это когда обеспечивается защита только для данных
строкового типа. Не забывайте о необходимости в проверке также и числовых
данных. Если приложение генерирует запрос типа SELECT * FROM table WHERE
ID=234 с вводом значения 234, пользователь сможет ввести значение 234 OR 1=1,
чтобы заставить приложение генерировать запрос SELECT * FROM table WHERE
ID=234 OR 1=1. В результате сервер будет извлекать каждую запись из таблицы.
Это приводит к отображению всех записей и излишней нагрузке на сервер. Самый
простой способ защиты от подобного рода атак - это ставить апостроф с двух
сторон числовой константы: SELECT * FROM table WHERE ID='234 f . При вводе
пользователем дополнительной информации, она становится частью строки. В
числовом контексте MySQL автоматически преобразует такую строку в число и
удаляет из нее любые замыкающие нецифровые символы.
Иногда некоторые думают, что если в базе данных содержатся только общедос-
тупные данные, ее защита не имеет смысла. Такое мнение в корне не верно. Даже
если разрешается отображать все записи из базы данных, по-прежнему должна
предусматриваться защита от атак типа отказа в обслуживании (которые, к при-
меру, используют описанный выше прием, что приводит к трате ресурсов серве-
ра). В противном случае ваш сервер может перестать отвечать на запросы автори-
зованных пользователей.
Ниже представлены шаги по проверке.
• Попробуйте ввести ' ' ' (апостроф) и '"' (кавычка) во всех ваших Web-формах.
Если MySQL выдаст какую-нибудь ошибку, сразу же разберитесь, с чем была
связана проблема.
• Попробуйте модифицировать любые динамические URL-адреса путем добав-
ления в них %22 (""), %23 ('#') и %27 (''')
• Попробуйте изменить типы данных в динамических URL-адресах с числовых
на символьные, содержащие символы из предыдущих примеров. Защита при-
ложения должна быть стабильна при атаках подобного рода.
• Попробуйте вводить не цифры, а буквы, пробелы или специальные символы в
числовых полях. Ваше приложение в таком случае должно удалять их перед
передачей в MySQL или выдавать ошибку. Передавать в MySQL непроверен-
ные значения очень опасно!
• Проверяйте размеры данных перед передачей в MySQL.
268 Глава 4. Администрирование баз данных

• Продумайте использование для вашего приложения при подключении к базе


данных пароля, отличного от имени пользователя, применяемого для целей
администрирования. Не предоставляйте приложениям никаких привилегий
доступа, которые не являются для них необходимыми.
• Многие API-интерфейсы предоставляют средства, позволяющие избежать ис-
пользования специальных символов в значениях данных. При правильном приме-
нении таких средств пользователи приложений не смогут вводить значения, кото-
рые приводят к генерированию приложением операторов, не соответствующих
вашим требованиям:
• MySQL С API - используйте API-вызов m y s q l r e a l e s c a p e s t r i n g ().
• MySQL++ - используйте модификаторы escape и quote для потоков запросов.
• РНР - используйте функцию mysql_escape_string(), основанную на функции
с таким же именем в MySQL С API. До РНР 4.0.3 вместо указанной исполь-
зуйте функцию addslashes ().
• Perl DBI - используйте метод quote () или символы-заполнители.
• Java JDBC - используйте объект PreparedStatement и символы-заполнители.
Остальные API-интерфейсы имеют аналогичные возможности.
• Не передавайте открытые (незашифрованные) данные через Internet. Такая ин-
формация доступна любому, у кого есть время и возможность перехватить и ис-
пользовать ее в своих собственных целях. Вместо этого пользуйтесь протоколами
с шифрованием данных, такими как SSL или SSH. MySQL поддерживает внут-
ренние SSL-соединения, начиная с версии 4.0.0. Переадресация SSH-портов мо-
жет использоваться, чтобы создать туннель, через который будут передаваться
зашифрованные (и сжатые) данные.
• Научитесь пользоваться утилитами tcpdump и strings. В большинстве случаев
проверить, зашифрованы ли потоки данных MySQL, можно с помощью команды,
подобной следующей:
shell> tcpdump -I -i ethO -w - src or dst port 3306 | strings
(Она работает в Linux и с незначительными изменениями должна работать в дру-
гих системах.) Будьте внимательны: если вы не видите данных в читабельном
формате, это не всегда означает, что они на самом деле зашифрованы. Если есть
необходимость в высокой степени защиты, следует проконсультироваться у спе-
циалиста по подобным вопросам.

4.3.2. Как защитить MySQL от хакеров


При подключении к серверу MySQL необходимо использовать пароль. Пароль не пе-
редается в виде открытого текста через соединение. Функции управления паролями во
время подключения клиентов в MySQL 4.1.1 получили дополнительную степень защи-
ты. При использовании старой версии MySQL или паролей старого (до версии 4.1.1)
формата, алгоритм шифрования более уязвим, и сообразительный хакер, который имеет
возможность перехватывать поток данных между клиентом и сервером, потратив опре-
деленные усилия, сможет такой пароль взломать. (За более подробной информацией о
различных методах управления паролями обратитесь в раздел 4.4.9.) Если соединение
между клиентом и сервером осуществляется через ненадежную сеть, следует использо-
вать SSH-туннель для шифрования связи.
4.3. Общие проблемы безопасности 269

Вся остальная информация передается в виде текста, который может прочитать лю-
бой, имеющий возможность наблюдать за соединением. Если это вызывает беспокойст-
во, попробуйте воспользоваться протоколом со сжатием данных (доступным в версиях
MySQL 3.22 и выше), который значительно затрудняет дешифровку. Чтобы еще больше
повысить степень безопасности соединения, следует использовать протокол SSH, кото-
рый обеспечивает шифрованное TCP/IP-соединение между сервером и клиентом
MySQL. Клиент Open Source SSH доступен на сайте http://www.openssh.org/, а ком-
мерческий SSH-клиент - на сайте h t t p : //www. ssh. com/.
В версии MySQL 4.0 и выше также доступна внутренняя OpenSSL-поддержка. См.
раздел 4.5.7.
Чтобы защитить систему MySQL, необходимо самым серьезным образом отнестись к
перечисленным ниже рекомендациям.
• Применяйте пароли для всех пользователей MySQL. Клиентскому приложению
не обязательно известно, кто именно работает с ним. Для клиент-серверных при-
ложений общепринято, что пользователь может указывать для клиентской про-
граммы любое имя пользователя. Например, каждый может воспользоваться про-
граммой mysql и подключиться под именем другого человека, просто вызвав ее
через mysql -u другой^пользователь имя_базы__данных, если для пользователя
другой_пользователь не установлен пароль. Если пароли есть у всех пользовате-
лей, подключиться при помощи учетной записи другого пользователя будет на-
много сложнее.
Чтобы изменить для пользователя пароль, используйте оператор SET PASSWORD.
Также можно обновить таблицу user прямо в базе данных mysql. Например, что-
бы изменить пароль для всех учетных записей MySQL с именем пользователя
root, потребуется предпринять следующие действия:
shell> mysql -u root
mysql> UPDATE mysql.user SET Password=PASSWORD('новый_пароль')
-> WHERE User='root 1 ;
mysql> FLUSH PRIVILEGES;
• He запускайте сервер MySQL от имени привилегированного (root) пользовате-
ля Unix. Это очень опасно, поскольку любой, имеющий привилегию FILE, смо-
жет создавать файлы как привилегированный (root) пользователь (например,
-root/.bashrc). Чтобы предотвратить подобные действия, mysql отказывается за-
пускаться от имени root до тех пор, пока это не будет указано явно, с помощью
опции —user=root.
Вместо этого mysqld можно запускать от имени простого непривилегированного
пользователя. Также есть возможность создать отдельную запись Unix с именем
mysql, чтобы обеспечить дополнительную степень защиты. Используйте эту учет-
ную запись только для администрирования MySQL. Чтобы запустить mysqld от
имени другого пользователя Unix, добавьте опцию user, определяющую имя
пользователя, в группу [mysqld] файла опций /etc/my.cnf или файла опций
my. cnf, который находится в каталоге данных сервера. Например:
[mysqld]
user=mysql
270 Глава 4. Администрирование баз данных

Это приводит к запуску сервера от имени назначенного пользователя, независимо


от того, запускается ли сервер вручную либо с помощью mysqldsafe или
mysql. server. Более подробную информацию можно найти в разделе А.3.2.
Запуск mysql от имени другого, непривилегированного (не root) пользователя
Unix не означает, что нужно поменять имя пользователя root в таблице user.
Имена пользователей для учетных записей MySQL не имеют ничего общего с
именами пользователей для учетных записей Unix.
• Запретите использование символических ссылок на таблицы. (Данную функцию
можно отключить с помощью опции —skipsymbolic-links.) Это особенно важно,
если mysqld запускается от имени root, поскольку каждый, кто имеет доступ для
записи в каталоги данных сервера, сможет удалить любой файл в системе! См.
раздел 6.6.1.2.
• Убедитесь, что только один пользователь Unix, имеющий привилегии чте-
ния/записи в каталогах баз данных, является пользователем, от имени которого
запускается mysqld.
• Не предоставляйте привилегию PROCESS или SUPER обычным пользователям. Вы-
ходные данные команды mysqladmin processlist отображают текст обрабаты-
ваемых на данный момент запросов, поэтому любой пользователь, которому раз-
решено выполнять эту команду, сможет просмотреть запрос другого пользовате-
ля, такой, например, как UPDATE user SET password=PASSWORD('not_secure').
Сервер mysqld резервирует дополнительное соединение для пользователей,
имеющих привилегию SUPER (или PROCESS в версиях до MySQL 4.0.2) так, чтобы
привилегированный (root) пользователь MySQL смог войти в систему и прове-
рить активность сервера, даже когда все обычные соединения на данный момент
заняты.
Привилегия SUPER может использоваться для завершения соединений клиентов,
смены режима работы сервера путем изменения значения системных переменных
и для управления серверами репликации.
• Не предоставляйте привилегию FILE обычным пользователям. Любой пользова-
тель, имеющий такую привилегию, в любом месте файловой системы сможет за-
писать файл с привилегиями демона mysqld! Чтобы хоть как-то защититься от
этого, в файлы, созданные с помощью SELECT... INTO OUTFILE, разрешена запись,
однако перезаписывать существующие файлы нельзя.
• Если вы не доверяете DNS, в таблицах привилегий используйте IP-адреса вместо
имен хостов. В любом случае будьте предельно осторожны при создании для таб-
лиц привилегий записей с именами хостов, которые содержат групповые символы!
• Чтобы ограничить число разрешенных для одной учетной записи соединений, ус-
тановите в mysqld переменную max_user_connections. Оператор GRANT тоже под-
держивает опции управления ресурсами, ограничивающие допустимую для одно-
го пользователя степень использования серверных ресурсов.

4.3.3. Опции запуска для mysqld, касающиеся


безопасности
Следующие опции mysqld влияют на степень безопасности системы:
4.3. Общие проблемы безопасности 271

• —local-infile[={0 11} ]. Если запустить сервер с — local-infile=0, клиенты не


смогут использовать операторы LOAD DATA. См. раздел 4.3.4.
• —safe-show-database. При использовании данной опции оператор SHOW
DATABASES будет отображать имена только тех баз данных, для доступа к которым
у пользователя имеется хоть какая-нибудь привилегия. Начиная с версии 4.0.2, эта
опция устарела и ни для чего не служит (по умолчанию включена). Теперь суще-
ствует привилегия SHOW DATABASES, которую можно использовать, чтобы управ-
лять доступом к базам данных для каждой учетной записи отдельно.
• —safe-user-create. Если данная опция включена, пользователь не сможет соз-
давать новых пользователей с помощью оператора GRANT до тех пор, пока у него
не будет привилегии INSERT для таблицы mysql.user. Чтобы пользователь имел
возможность создавать новых пользователей с теми привилегиями, которые у не-
го есть право предоставлять, ему следует предоставить следующую привилегию:
mysql> GRANT INSERT(user) ON mysql.user TO 'имя_пользователя}@'имя_хостах;
Это гарантирует, что пользователь не сможет изменять непосредственно ни один
из столбцов привилегий, и для предоставления привилегий другим пользователям
ему придется использовать оператор GRANT.
• —secure-auth. Запрещает аутентификацию учетным записям, использующим
старые (до версии 4.1) пароли. Эта опция доступна, начиная с MySQL 4.1.1.
• —skip-grant-tables. При установке данной опции сервер совсем не будет ис-
пользовать систему привилегий. То есть каждый пользователь получает полный
доступ ко всем базам данных! (Можно сделать так, чтобы сервер снова начал ис-
пользовать таблицы привилегий, с помощью команды mysldadmin flush-
privileges или mysqladmin reload, либо же оператора FLUSH PRIVILEGES.)
• —skip-name-resolve. Преобразование имен хостов не выполняется. Все значения
столбцов Host в таблицах привилегий должны хранить IP-адреса или localhost.
• —skip-networking. Запрещает TCP/IP-соединения через сеть. Все подключения к
mysqld должны осуществляться через файлы сокетов Unix. Эта опция не подходит
для версий MySQL, предшествующих 3.23.27, которые используются вместе с па-
кетом MIT-pthreads, поскольку на тот момент файлы сокетов Unix не поддержи-
вались потоками MIT-pthreads.
• —skip-show-database. При установке данной опции оператор SHOW DATABASES
доступен только пользователям, имеющим привилегию SHOW DATABASES, и ото-
бражает имена всех баз данных. Если эта опция не используется, SHOW DATABASES
разрешен для всех пользователей, но отображает имя каждой базы данных, только
если пользователь имеет привилегию SHOW DAATABASES или какую-нибудь другую
привилегию для базы данных.

4.3.4. Вопросы безопасности и оператор LOAD DATA LOCAL


Оператор LOAD DATA может загружать файл, находящийся на хосте сервера или на
хосте клиента, когда указано ключевое слово LOCAL.
При поддержке версии LOCAL операторов LOAD DATA существуют две потенциальные
проблемы, касающиеся безопасности системы:
272 Глава 4. Администрирование баз данных

• Передача файла с хоста клиента на хост сервера инициируется сервером MySQL.


Теоретически можно собрать сервер с исправлениями, который бы заставлял кли-
ентскую программу передавать выбранный сервером файл, а не файл, указанный
клиентом в операторе LOAD DATA. Такой сервер мог бы получать доступ к любому
файлу на хосте клиента, к которому у пользователя имеется доступ по чтению.
• В Web-среде, где клиенты подключаются с Web-сервера, пользователь мог бы ис-
пользовать оператор LOAD DATA LOCAL для чтения любых файлов, к которым про-
цесс Web-сервера имеет доступ для чтения (предполагается, что пользователь
может выполнять любые команды, касающиеся SQL-сервера). В такой среде кли-
ент по отношению к MySQL-серверу фактически является Web-сервером, а не
программой, запускаемой пользователем, которая подключается к Web-серверу.
Чтобы решить такие проблемы безопасности, для оператора LOAD DATA LOCAL в
MySQL 3.23.49 и MySQL 4.0.2 (4.0.13 для Windows) были внесены определенные изме-
нения:
• По умолчанию все клиенты и библиотеки MySQL в бинарных дистрибутивах для
совместимости с MySQL 3.23.48 и ниже компилируются с опцией —enable-
local-infile.
• Если во время сборки MySQL из исходного дистрибутива при его конфигуриро-
вании опция —enable-local-infile не указывается, никакие клиенты не смогут
использовать оператор LOAD DATA LOCAL до тех пор, пока он не будет записан явно
ДЛЯ вызова raysql_options (. . . MYSQL_OPT_LOCAL_INFILE, 0).
• Можно заблокировать все команды LOAD DATA LOCAL со стороны сервера, запус-
тив mysqld с опцией —local-inf ile=0.
• Для клиента командной строки mysql оператор LOAD DATA LOCAL можно разбло-
кировать, задав опцию —local-inf i l e [=1], или заблокировать через опцию
—local-infile=0. Аналогично для mysqlimport опция —local или -L разрешает
локальную загрузку файлов данных. В любом случае, чтобы успешно использо-
вать операцию локальной загрузки, сначала потребуется соответствующим обра-
зом настроить сервер.
• Если оператор LOAD DATA LOCAL INFILE заблокирован на сервере или клиенте,
клиент при попытке его выполнить получит следующее сообщение об ошибке:
ERROR 1148: The used command is not allowed with this MySQL version
ОШИБКА 1148: Используемая команда недопустима в данной версии MySQL

4.4. Система привилегий доступа MySQL


В MySQL реализована расширенная, а не стандартная система привилегий и безо-
пасности. В данном разделе описываются особенности ее функционирования.

4.4.1. Функции системы привилегий


Первоначальная функция системы привилегий MySQL связаны с аутентификацией
пользователя, подключающегося с определенного хоста, и ассоциированием его с при-
вилегиями базы Данных, такими как SELECT, INSERT, UPDATE И DELETE.
4.4. Система привилегий доступа MySQL 273

Дополнительные функции включают возможность наличия анонимного пользователя


и возможность предоставления привилегий специальным MySQL-функциям, таким как
LOAD DATA INFILE и операции по администрированию.

4.4.2. Как работает система привилегий


Система привилегий MySQL гарантирует, что каждый пользователь может выпол-
нять только разрешенные ему операции. Когда вы подключаетесь к серверу MySQL как
пользователь, ваша личность определяется по имени хоста, с которого вы подключае-
тесь, и по имени пользователя, которое вы указываете. Система привилегий предос-
тавляет привилегии в соответствии с вашей личностью и тем, что вы хотите делать.
Во время идентификации MySQL анализирует и имя хоста, и имя пользователя, так
как процент того, что указанное имя пользователя принадлежит одному и тому же чело-
веку во всей сети Internet, слишком мал. Например, пользователь joe, который подклю-
чается с office.com, совсем не обязательно тот же самый человек, что и пользователь
joe, подключающийся с elswhere.com. MySQL справляется с этой проблемой, позволяя
различать пользователей, подсоединяющихся с разных хостов, но имеющих одно и то же
имя пользователя: можно предоставить joe один набор привилегий для подключений с
office. com, и совершенно другой - для подсоединений с elswhere. com.
В MySQL управление доступом подразумевает два этапа:
• Первый этап: сервер проверяет, разрешено ли вам вообще подключаться.
• Второй этап (предполагает, что разрешение на подключение у вас имеется): сер-
вер проводит верификацию каждого вашего оператора на предмет достаточного
количества привилегий для его выполнения. Например, при попытке выбрать
строки в таблице базы данных или удалить таблицу из базы данных, сервер про-
веряет, есть ли у вас привилегия SELECT для таблицы или, во втором случае, при-
вилегия DROP для базы данных.
Если привилегии изменяются (вами или кем-либо другим) в то время, когда вы под-
ключены к серверу, эти изменения не обязательно вступят в силу сразу же при выполне-
нии следующего оператора. Более подробную информацию можно найти в разделе 4.4.7.
Все решения, касающиеся управления доступом, основаны на копиях таблиц привилегий
в памяти.
Обычно обработка содержимого таблиц привилегий осуществляется косвенно, через
использование операторов GRANT и REVOKE для настройки учетных записей и управления
привилегиями, доступными каждой из них. В данном разделе описана базовая структура
таблиц привилегий, также то, как сервер использует их содержимое при взаимодействии
с клиентами.
Сервер использует таблицы user, db и host из базы данных mysql на обоих этапах
управления доступом. Столбцы этих таблиц привилегий представлены в табл. 4.2.
На втором этапе управления доступом (верификация запросов), если запрос подразу-
мевает обращение к таблицам, сервер может дополнительно провести сверку с таблица-
ми tables_priv или columnspriv, что обеспечивает лучшее управление доступом на
уровне таблиц и столбцов. Столбцы таких таблиц представлены в табл. 4.3.
274 Глава 4. Администрирование баз данных

Таблица 4.2. Столбцы таблиц user, db и host


Таблица user Таблица db Таблица host
Столбцы контекста
Host Host Host
User Db Db
Password User
Столбцы привилегий
Select priv Select priv Select priv
Insert priv Insert priv Insert priv
Update_priv Update priv Update priv
Delete priv Delete priv Delete priv
Index_priv Index_priv Index priv
Alter_priv Alter_priv Alter priv
Create priv Create priv Create priv
Drop priv Drop priv Drop priv
Grant_priv Grant_priv Grant priv
References priv References priv References_priv
Reload priv
Shutdown priv
Process_priv
File priv
Show db priv
Super priv
Create_tmp table priv Create tmp table priv Create tmp table priv
Lock tables priv Lock tables priv Lock_tables__priv
Execute priv
Repl_slave_priv
Repl client_priv
ssl_type
ssl cipher
x509 issuer
x509_subject
max questions
max updates
max connections
4.4. Система привилегий доступа MySQL 275

Таблица 4.3. Столбцы таблиц tables_priv и columns_priv


Таблица tables_priv Таблица columnsjpriv
Столбцы контекста
Host Host
Db Db
User User
Table_name Table_name
Column name

Столбцы привилегий
Table priv Column priv
Column_priv
Другие столбцы
Timestamp Timestamp
Grantor

Столбцы Timestamp и Grantor на данный момент не используются, и поэтому больше


обсуждаться не будут.
Каждая таблица привилегий содержит столбцы контекста и столбцы привилегий:
• Столбцы контекста определяют область действия каждой записи (строки) в таб-
лице, то есть контекст, в котором та или иная запись применяется. Например,
строка таблицы user, значения в столбцах Host и User которой равны, соответст-
венно, 'thomas.loc.gov' и 'bob', используется для аутентификации подключе-
ний к серверу с хоста thomas.loc.gov, осуществляемых клиентом с именем поль-
зователя bob. Точно так же строка таблицы, значения в столбцах Host, User и Db
которой хранятся ' thomas. loc. gov', 'bob' и ' reports', будет использоваться, ко-
гда bob попытается подключиться с хоста thomas.loc.gov, чтобы получить доступ
к базе данных reports. Таблицы tables_priv и columns_priv содержат столбцы,
с именами таблиц или комбинациями имен таблиц и столбцов, к которым приме-
няется каждая запись.
• В столбцах привилегий указаны привилегии, предоставляемые записью в таблице,
то есть выполнение каких операций разрешено. Чтобы составить полное описание
привилегий пользователя, сервер компонует информацию из самых разных таб-
лиц привилегий. Правила, необходимые для осуществления этого процесса, пере-
числены в разделе 4.4.6.
Столбцы контекста содержат строковые значения, объявленные так, как показано в
табл. 4.4. Значение по умолчанию для каждого столбцов - пустая строка.
До версии MySQL столбец Db был объявлен как CHAR (32) в одних таблицах и как
CHAR(60) в других.
Что касается проверки доступа, при сравнении значений Host регистр символов не
учитывается. Значения User, Password, Db и Table_name от регистра зависят. Значения
Column_name в MySQL 3.22.12 и последующих версиях к регистру не чувствительны.
276 Глава 4. Администрирование баз данных

Таблица 4.4. Столбцы контекста

Имя столбца Тип


Host CHAR(60)
User CHAR(16)
Password CHAR(16)
Db CHAR(64)
Table_name CHAR(60)
Column name CHAR(60)

В таблицах user, db и host каждая привилегия указана в отдельном столбце, объяв-


ленном как ENUM (' N ' , ' Y') DEFAULT ' N'. Другими словами, каждая привилегия может
быть включена или отключена; по умолчанию устанавливается значение ' N' (отключена).
В таблицах tables_priv и columns_priv столбцы привилегий объявлены как столбцы
SET. Значения в этих столбцах могут содержать любую комбинацию привилегий, кон-
тролируемых таблицей (см. табл. 4.5):
Таблица 4.5. Столбцы привилегий
Имя таблицы Имя столбца Возможные элементы набора
tables_priv Table_priv 'Select f , ' I n s e r t ' , 'Update', 'Delete',
'Create', 'Drop', 'Grant', 'References',
'Index', 'Alter'
tables_priv Columnjpriv ' S e l e c t ' , ' I n s e r t ' , 'Update', 'References'
columns_priv Column_priv 'Select', ' I n s e r t ' , 'Update', 'References'

Если выражаться кратко, то сервер использует таблицы привилегий следующим об-


разом:
• Столбцы контекста таблицы user определяют, отклонить или разрешить входя-
щие соединения. Для разрешенных соединений любые предоставленные в табли-
це user привилегии обозначают глобальные привилегии пользователя (то есть это
привилегии суперпользователя). Такие привилегии применяются ко всем храня-
щимся на сервере базам данных.
• Столбцы контекста таблицы db определяют, какие пользователи, с каких хостов и
к каким базам данных могут получать доступ. Столбцы привилегий определяют,
какие операции разрешены. Привилегия, предоставленная на уровне базы данных,
распространяется на базу данных и все ее таблицы.
• Таблица host используется вместе с таблицей db, когда необходимо, чтобы опре-
деленная запись из таблицы db применялась сразу к нескольким хостам. Напри-
мер, если требуется, чтобы пользователь мог получать доступ к базе данных с
разных хостов сети, оставьте значение столбца Host в записи таблицы db этого
пользователя пустым, а затем заполните таблицу host, внося записи для каждого
из этих хостов. Данный механизм более подробно описывается в разделе 4.4.6.
4.4. Система привилегий доступа MySQL 277

| На заметку!
Щ Применение операторов GRANT и REVOKE никак не отражается на таблице host. Большинство
%, установок MySQL вообще не нуждается в этой таблице.

• Таблицы tables_priv и columnspriv схожи с таблицей db, но характеризуются


разбиением более мелкого уровня: они применяются уже на уровнях таблиц и
столбцов, а не на уровне базы данных. Привилегия, предоставляемая на уровне
таблицы, распространяется на таблицу и все ее столбцы. Привилегия, предостав-
ленная на уровне столбца, распространяется только на конкретный столбец.
Административные привилегии (такие как RELOAD или SHUTDOWN) задаются только в
таблице user, потому что операции администрирования представляют собой операции
на самом сервере и не являются специальными для баз данных. Таким образом, перечис-
лять эти привилегии в остальных таблицах привилегий не имеет смысла. Фактически,
чтобы определить, имеете ли вы права на выполнение операции по администрированию,
сервер должен обратиться только к таблице user.
Привилегия FILE тоже задается только в таблице user. Она не представляет собой
административную привилегию как таковую, но возможность считывания и записи фай-
лов на хосте сервера не зависит от базы данной, к которой вы получаете доступ.
Сервер mysqld считывает и заносит в память содержимое таблиц привилегий во вре-
мя запуска. Заставить сервер провести повторное считывание таблиц можно с помощью
оператора FLUSH PRIVILEGES или команд mysqladmin flush-privileges и mysqladmin
reload. В разделе 4.4.7 описано, когда и как вносимые в таблицы привилегий изменения
вступают в силу.
При изменении содержимого таблиц привилегий не помешает убедиться, что вноси-
мые изменения устанавливают привилегии в соответствии с вашими желаниями. Один
из способов проверить предоставленные конкретной учетной записи привилегии пред-
полагает использование оператора SHOW GRANTS. Например, чтобы определить привиле-
гии, предоставленные учетной записи, значения Host и User которой соответствуют
рс84. example. com и bob, введите следующую команду:
mysql> SHOW GRANTS FOR 'bob'@'pc84.example.com•;
Полезным инструментом диагностики является сценарий mysqlaccess, который для
дистрибутива MySQL предоставил Ив Карлье (Yves Carlier). Чтобы узнать, как он рабо-
тает, вызовите mysqlaccess с опцией —help. Обратите внимание, что mysqlaccess
управляет доступом, используя только таблицы user, db и host. Привилегии, заданные в
таблицах tables_priv и columnspriv, он не проверяет.
Дополнительную справочную информацию по диагностике связанных с привилегия-
ми проблем можно найти в разделе 4.4.8. Общие советы по вопросам обеспечения безо-
пасности представлены в разделе 4.3.

44.3. Привилегии, предоставляемые MySQL


Информация о привилегиях для учетных записей хранится в таблицах user, db, host,
tables_priv и columnspriv базы данных mysql. Сервер MySQL считывает и заносит
содержимое этих таблиц в память во время запуска, а повторное считывание осуществ-
ляет при обстоятельствах, описанных в разделе 4.4.7.
Названия, используемые в данном руководстве для ссылки на предоставляемые
MySQL привилегии, перечислены в табл. 4.6. При этом также представлены имена
278 Глава 4. Администрирование баз данных

столбцов таблицы, ассоциируемых с каждой привилегией в таблицах привилегий, и кон-


текст, в котором применяется та или иная привилегия. Дополнительную информацию о
значении каждой переменной можно найти в книге "MySQL. Справочник по языку ".
Таблица 4.6. Названия для ссылки на предоставляемые MySQL привилегии
Привилегия Столбец Контекст
ALTER Alter_priv таблицы
DELETE Delete_priv таблицы
INDEX Index_priv таблицы
INSERT Insert_priv таблицы
SELECT Select_priv таблицы
UPDATE Update_priv таблицы
CREATE Create_priv базы данных, таблицы или индексы
DROP Drop_priv базы данных или таблицы
GRANT Grant_priv базы данных или таблицы
REFERENCES References_priv базы данных или таблицы
CREATE TEMPORARY TABLES Create_tmp_tablejpriv администраторы сервера
EXECUTE Executejpriv администраторы сервера
FILE File_priv доступ к файлам на хосте сервера
LOCK TABLES Lock_tables_priv администраторы сервера
PROCESS Processjpriv администраторы сервера
RELOAD Reload_priv администраторы сервера
REPLICATION CLIENT Repl_client_priv администраторы сервера
REPLICATION SLAVE Repl_slave_priv администраторы сервера
SHOW DATABASES Show_dbj?riv администраторы сервера
SHUTDOWN Shutdown_priv администраторы сервера
SUPER Super_priv администраторы сервера

П р и в и л е г и и CREATE TEMPORARY TABLES, EXECUTE, LOCK TABLES, REPLICATION CLIENT,


REPLICATION SLAVE, SHOW DATABASES И SUPER ПОЯВИЛИСЬ В M y S Q L 4 . 0 . 2 .
Привилегии EXECUTE и REFERENCES в настоящее время не используются.
Привилегии SELECT, INSERT, UPDATE и DELETE позволяют выполнять операции со стро-
ками в существующих таблицах базы данных.
Операторы SELECT требуют наличия привилегии SELECT, только если они на самом
деле извлекают строки из таблицы. Некоторые операторы SELECT не обращаются к таб-
лицам и могут быть выполнены даже без разрешения на доступ к базам данных. Напри-
мер, можно использовать клиент raysql в качестве простого калькулятора для вычисле-
ния выражений, которые не ссылаются на таблицы:
mysql> SELECT 1+1;
mysql> SELECT PI()*2;
4.4. Система привилегий доступа MySQL 279

Привилегии CREATE и DROP позволяют создавать новые базы данных и таблицы и л и


удалять существующие. П р и предоставлении привилегии DROP д л я доступа к базе д а н -
ных mysql пользователю, этот пользователь может удалить базу данных, в которой хра-
нятся привилегии доступа M y S Q L !
Привилегия INDEX позволяет создавать и л и удалять индексы. О н а распространяется
на существующие таблицы. П р и наличии привилегии CREATE д л я таблицы появляется
возможность включать индексные д е ф и н и ц и и в оператор CREATE TABLE.
Привилегия ALTER позволяет использовать оператор ALTER TABLE д л я изменения
структуры таблиц, а также д л я и х переименования.
Привилегия GRANT позволяет предоставлять другим пользователям те привилегии, к о -
торые имеются у вас самих.
Привилегия FILE разрешает считывать и записывать ф а й л ы н а хосте сервера с помо-
щ ь ю операторов LOAD DATA INFILE и SELECT...INTO OUTFILE. Пользователь, и м е ю щ и й
привилегию FILE, может читать л ю б о й общедоступный либо доступный д л я M y S Q L
файл н а хосте сервера. ( Э т о подразумевает, что пользователь может считывать л ю б о й
файл и з любого каталога базы данных, поскольку сервер имеет доступ к каждому и з
этих файлов.) Привилегия FILE также позволяет пользователю создавать новые файлы в
л ю б о м каталоге, к которому сервер M y S Q L имеет доступ п о записи. Перезаписать суще-
ствующие файлы невозможно.
Остальные привилегии используются д л я операций администрирования, большинст-
во из которых выполняется с п о м о щ ь ю программы mysqladmin и л и SQL-операторов.
Таблица 4.7 иллюстрирует, какие команды mysqladmin разрешает выполнять каждая ад-
министративная привилегия.
Т а б л и ц а 4.7. Команды mysqladmin, разрешенные административными привилегиями
Привилегия Команды, разрешенные обладателю привилегий
RELOAD flush-hosts, flush-logs, flush-privileges, flush-status,
flush-tables,flush-threads, refresh, reload
SHUTDOWN shutdown
PROCESS processlist
SUPER kill

Команда reload заставляет сервер выполнить повторное считывание и занесение в


память таблиц привилегий, flushprivileges является синонимом reload. Команда
refresh закрывает и открывает заново журнальные файлы, а также очищает все табли-
цы. Другие команды flush-xxx выполняют функции, подобные функциям refresh, но
являются более специфическими, и поэтому в отдельных случаях их применение пред-
почтительней. Например, если необходимо очистить только журнальные файлы, лучше
использовать команду flush-logs, чем refresh.
Команда shutdown завершает работу сервера. Эта команда может быть выполнена
только из программы mysqladmin. Соответствующий SQL-оператор не предусмотрен.
Команда processlist отображает информацию о потоках на сервере (то есть об опе-
раторах, которые выполняются клиентами, соотнесенными с другими учетными запися-
ми). Команда k i l l удаляет все серверные потоки. Отображать или удалять собственные
потоки можно всегда, но вот чтобы отобразить потоки, инициированные другими поль-
280 Глава 4. Администрирование баз данных

зователями, понадобится привилегия PROCESS, а чтобы удалить - привилегия SUPER. До


версии MySQL 4.0.2, в которой была введена привилегия SUPER, за возможность как про-
сматривать, так и удалять потоки других клиентов отвечала привилегия PROCESS.
Привилегия CREATE TEMPORARY TABLES позволяет использовать ключевое слово
TEMPORARY В операторах CREATE TABLE.
Привилегия LOCK TABLES разрешает применение явных операторов LOCK TABLES при
блокировке таблиц, для которых у вас имеется привилегия SELECT. Сюда входит исполь-
зование блокировки записи, что предупреждает считывание заблокированной таблицы
другим пользователем.
Привилегия REPLICATION CLIENT ПОЗВОЛЯет ИСПОЛЬЗОВать SHOW MASTER STATUS И SHOW
SLAVE STATUS.
Привилегия REPLICATION SLAVE должна предоставляться учетным записям, которые
используются подчиненными серверами, когда они подключаются к текущему серверу
как к главному. Без этой привилегии подчиненный сервер не может запрашивать обнов-
ления, примененные к базам данных на главном сервере.
Привилегия SHOW DATABASES разрешает учетной записи просматривать имена баз
данных с помощью оператора SHOW DATABASE. Учетные записи, не имеющие данной при-
вилегии, видят только базы данных, для доступа к которым у них есть хоть какая-нибудь
привилегия, и совсем не могут использовать оператор, если сервер запускался с опцией
—skip-show-database.
В целом лучше всего предоставлять привилегии только тем учетным записям, кото-
рым они необходимы, но следует быть особенно осторожными при предоставлении при-
вилегий администрирования:
• Привилегия GRANT разрешает пользователями передавать свои привилегии другим
пользователям. Два пользователя с разными привилегиями, получив привилегию
GRANT, смогут объединить имеющиеся у них привилегии.
• Привилегия ALTER может быть использована для разрушения всей системы при-
вилегий путем переименования таблиц.
• Не исключено злоупотребление привилегией FILE, когда в таблицу базы данных
передаются любые файлы, которые сервер MySQL может считывать на хосте сер-
вера. Сюда входят все общедоступные файлы и файлы из каталога данных серве-
ра. Затем, получив доступ к этой таблице при помощи SELECT, ее содержимое
можно будет перенести на хост клиента.
• Не исключено злоупотребление привилегией SHUTDOWN, когда другим пользовате-
лям полностью отказывается в обслуживании путем завершения работы сервера.
• Привилегия PROCESS может использоваться для просмотра нешифрованного тек-
ста выполняющихся на данный момент запросов, включая запросы, которые уста-
навливают или изменяют пароли.
• Привилегия SUPER может быть использована для удаления других клиентов или
изменения режима работы сервера.
• Привилегии, предоставляемые для доступа к самой базе данных mysql, могут
быть использованы для изменения паролей и другой информации, касающейся
привилегий доступа. Пароли хранятся в зашифрованном виде, поэтому злоумыш-
ленник не может просто прочитать их и узнать, как они выглядят в обычном тек-
стовом формате. Однако, пользователь, имеющий доступ для записи к столбцу
4.4. Система привилегий доступа MySQL 281

Password в таблице user, вполне может изменить пароль какой-нибудь учетной


записи, а затем с помощью этой учетной записи подключиться к серверу MySQL.
Для системы привилегий MySQL существуют и определенные запреты:
• Нельзя явно указать, что какому-нибудь определенному пользователю в доступе
должно быть отказано. Другими словами, выбрать пользователя, а затем запре-
тить ему подключение не получится.
• Нельзя указать, что пользователь имеет привилегии для создания и удаления таб-
лиц в базе данных, но не имеет привилегий для создания и удаления самой базы
данных.

4.4.4. Подключение к серверу MySQL


Обычно при получении доступа к MySQL в клиентских программах указываются
следующие параметры соединения:
• Имя хоста, на котором работает сервер MySQL.
• Ваше имя пользователя.
• Ваш пароль.
Например, клиент mysql можно запустить следующим образом из командной строки
(обозначенной здесь через shell>):
shell> mysql -h имя_хоста -и имя_пользователя -рпароль
Альтернативными формами опций -h, -u и -р являются —hos 1=имя_хоста, —user=
имя_пользователя и —password=napcwib. Обратите внимание на то, что пробел между -р
или —password и следующим дальше паролем не допускается.
Если используется опция -р или —password, но не указывается значение пароля,
клиентская программа выдаст подсказку о необходимости ввода пароля. Во время ввода
сам пароль не отображается. Это более безопасно, чем указывать пароль в командной
строке. Любой пользователь вашей системы может увидеть указанный в командной
строке пароль, выполнив команду типа auxww. См. раздел 4.5.6.
Клиентские программы MySQL для любой не указываемой вами опции параметров
соединения используют значения по умолчанию:
• Значение по умолчанию для имени хоста - localhost.
• Значение по умолчанию для имени пользователя - ODBC (в Windows) или регист-
рационное имя (в Unix).
• Пароль не предоставляется, если отсутствует -р.
Таким образом, для пользователя Unix с регистрационным именем joe все представ-
ленные ниже команды эквивалентны:
shell> mysql -h localhost -u joe
shell> mysql -h localhost
shell> mysql -u joe
shell> mysql
Другие клиенты MySQL ведут себя аналогично.
Можно задавать различные значения по умолчанию, которые будут использоваться во
время установки соединения так, чтобы не приходилось вводить их в командной строке
каждый раз при вызове клиентской программы, и сделать это можно двумя способами:
282 Глава 4. Администрирование баз данных

• Существует возможность задать параметры соединения в разделе [client] файла


опций. Соответствующий раздел файла может выглядеть следующим образом:
[client]
host=ммя_хоста
изег=имя_пользователя
password=napcwib
Файлы опций более подробно описаны в разделе 3.3.2.
• Некоторые параметры соединения можно задать с помощью переменных окруже-
ния. Хост для mysql можно задать через MySQL_HOST, а имя пользователя MySQL -
с помощью USER (только для Windows и NetWare). Пароль может быть задан по-
средством MYSQLPWD, хотя это и небезопасно; см. раздел 4.5.6. Список перемен-
ных представлен в приложении Б.

4.4.5. Управление доступом, этап первый:


верификация подключения
При попытке подключиться к серверу MySQL сервер разрешает соединение либо от-
казывает в нем, основываясь на информации о вашей личности и том, можете ли вы под-
твердить ее путем ввода правильного пароля. Если нет, сервер полностью отказывает
вам в доступе. Если да, сервер разрешает соединение, затем инициирует этап второй и
ожидает запросов.
Ваша личность определяется по двум типам информации:
• Хост клиента, с которого вы подключаетесь.
• Ваше имя пользователя MySQL.
Проверка личности выполняется с использованием информации из трех столбцов
контекста в таблице user (Host, User и Password). Сервер разрешает подключение только
в том случае, если значения в столбцах Host и USER таблицы user совпадают с введен-
ными именем хоста клиента и именем пользователя и при этом клиент предоставляет
пароль, указанный в столбце PASSWORD.
Значения Host в таблице user могут быть заданы следующим образом:
• Значение в столбце Host может соответствовать имени хоста или IP-адресу, либо
же ' local host' для обозначения локального хоста.
• В значениях столбца Host могут использоваться групповые символы '%' и '_'. Они
имеют то же значение, что и в операциях сравнения с образцом, выполняемых
оператором LIKE. Например, значение ' %' соответствует имени любого хоста, в то
время как значение '%.mysql.com1 будет соответствовать имени любого хоста в
домене mysql. com.
• Начиная с версии MySQL 3.23, для значений Host, указанных в виде IP-адресов,
можно задать сетевую маску, обозначающую число бит адреса для номера в сети,
например:
mysql> GRANT ALL PRIVILEGES ON db.*
-> TO david@ f 192.58.197.0/255.255.255.0';
Это разрешает пользователю с именем david подключаться с любого хоста клиен-
та с IP-адресом 1Р-адрес_клиента, для которого выполняется следующее условие:
1Р-адрес_клиента & сетевая_маска = 1Р-адрес_хоста
4.4. Система привилегий доступа MySQL 283

Таким образом, для вышеуказанного оператора GRANT:


1Р-адрес_клиента & 255.255.255.0 = 192.58.197.0
IP-адреса, которые отвечают этому условию и могут подсоединяться к серверу
MySQL, находятся в диапазоне от 192.58.197.0 до 192.58.197.255.
• Пустое значение в столбце Host таблицы db означает, что предоставляемые им при-
вилегии должны комбинироваться с привилегиями в записи таблицы host, соответ-
ствующей имени хоста клиента. Привилегии комбинируются с помощью операции
AND (операции логического И), а не операции OR (операции логического ИЛИ). Бо-
лее подробную информацию о таблице host можно найти в разделе 4.4.6.
Пустое значение в столбце Host других таблиц привилегий будет обозначать то
же, что и ' %'.
Поскольку в столбце Host могут использоваться значения группового IP-адреса (на-
пример, '144.155.166.%' для сопоставления с каждым хостом в подсети), злоумышлен-
ник может употребить это в своих целях, назвав хост 144.155.166.somewhere.com. Что-
бы предупредить подобные попытки, MySQL запрещает сопоставление по именам хос-
тов, которые начинаются с точки или цифры. Таким образом, имена хостов типа
1.2.foo.com никогда не будут сопоставляться со значениями в столбцах Host таблиц
привилегий. Значению группового IP-адреса могут соответствовать только IP-адреса, но
не имена хостов.
В столбце User использовать групповые символы нельзя, но можно задавать пустое
значение, соответствующее любому имени. Если в записи таблицы user, соответствую-
щей входящему соединению, содержится пустое значение для имени пользователя, этот
пользователь рассматривается как анонимный, не имеющий имени, а не как пользова-
тель с именем, которое было на самом деле задано клиентом. Это означает, что пустое
имя пользователя будет применяться для всех последующих проверок доступа на про-
тяжении данного соединения (то есть во время второго этапа).
Столбец Password может не содержать никакого значения (быть пустым). Это не
групповой символ и вовсе не означает, что подойдет любой пароль, а только то, что
пользователь должен подключаться без указания пароля.
Непустые значения Password в таблице user представляют собой зашифрованные па-
роли. MySQL не хранит пароли в форме открытого текста, чтобы любой мог их увидеть.
Наоборот, пароль, предоставляемый пользователем, который пытается подключиться к
серверу, шифруется (с помощью функции PASSWORD ()). Зашифрованный пароль затем
используется во время процесса подключения для проверки, является ли вводимый па-
роль корректным (при этом зашифрованный пароль никогда не пересылается через со-
единение). С точки зрения MySQL зашифрованный пароль является РЕАЛЬНЫМ, по-
этому никому нельзя предоставлять к нему доступ! В частности, не разрешайте обыч-
ным пользователям доступ по чтению к таблицам в базе данных mysql!
Начиная с версии 4.1, MySQL использует более сложный метод аутентификации, ко-
торый обеспечивает лучшую, нежели в более ранних версиях, защиту паролей во время
процесса подключения. Система остается безопасной, даже если перехвачены пакеты
TCP/IP или сама база данных mysql. Шифрование паролей более подробно обсуждается
в разделе 4.4.9.
Приведенные в табл. 4.8 примеры иллюстрируют, как различные комбинации значе-
ний в столбцах Host и User таблицы user применяются к входящим соединениям.
284 Глава 4. Администрирование баз данных

Таблица 4.8. Примеры значений в столбцах Host и User

Значение в
Значение в столбце Host столбце User Совпавшие с записью подключения
'thomas.loc.gov' 'fred' fred, подключающийся из
thomas.loc.gov.
!
' thomas. loc. gov' ' Любой пользователь, подключающийся
из thomas.loc.gov.
' %' ' fred' fred, подключающийся с любого хоста.
' %' '' Любой пользователь, подключающийся
с любого хоста.
1
%. loc. gov' ' fred' fred, подключающийся с любого хоста
в домене loc.gov.
'х.у.%' 'fred' fred, подключающийся из х.у.net,
х. у. com, х. у. edu и так далее (это, ско-
рее всего, бесполезная комбинация).
'144.155.166.177' 'fred' fred, подключающийся с хоста,
IP-адрес которого выглядит как
144.155.166.177.
'144.155.166.%' 'fred' fred, подключающийся с любого хоста
в подсети 144.155.166 класса С.
'144.155.166.0/255.255.255.0' ' fred' To же, что и в предыдущем примере.

Вполне возможно, чтобы имя хоста клиента и имя пользователя входящего соедине-
ния соответствовали более чем одной записи в таблице user. Вышеуказанный набор
примеров демонстрирует следующее: сразу несколько из представленных записей соот-
ветствуют соединению, устанавливаемому пользователем fred с thomas. loc. gov.
Если соответствующих (совпадающих) записей несколько, сервер должен опреде-
лять, какую из них использовать. Он разрешает эту проблему следующим образом:
• Каждый раз, когда сервер считывает таблицу user, он выполняет сортировку за-
писей.
• Когда клиент пытается подключиться, сервер просматривает записи в отсортиро-
ванном порядке.
• Сервер использует первую запись, которая совпадает с именем хоста клиента и
именем пользователя.
Чтобы посмотреть, как это работает, предположим, что таблица user выглядит сле-
дующим образом:

I Host ! User |
+ + +
I % | root I
I % I Jeffrey I
I localhost | root |
I localhost | I
4.4. Система привилегий доступа MySQL 285

При считывании таблицы сервер сначала упорядочивает записи с наиболее точными


значениями в столбце Host. Таковыми являются буквенные имена хостов и цифровые
номера IP-адресов. ' %' означает "любой хост" и является наименее точным. Записи с
одинаковыми значениями в столбце Host упорядочиваются сначала по наиболее точным
значениям столбца User (пустое значение в столбце User означает "любой пользователь"
и является наименее точным). После сортировки представленная выше таблица будет
выглядеть так:
+ + +-
! Host | User I ...
+ + +-
I localhost | root | ...
I localhost ! | ...
I % | Jeffrey | ...
I % | root | ...
+ + +_
Когда клиент пытается подключиться, сервер просматривает отсортированные запи-
си и использует первую подходящую. Для соединения, устанавливаемого Jeffrey из
localhost, подходят стразу две записи в таблице: запись со значением 'localhost 1 в
столбце Host и значением ' ' в столбце User, а также запись со значениями '%' и
' J e f f r e y ' соответственно. Первой в отсортированной таблице стоит запись
'localhost', она и будет использоваться сервером.
Теперь рассмотрим другой пример. Предположим, что таблица user выглядит так:
4- + +-
I Host I User | ...
+
+ +-
I % I Jeffrey | ...
I thomas.loc.gov | | ...
+ 4- 4--
После сортировки она будет выглядеть следующим образом:
+
+ +-
I Host I User I ...
4. + +-
| thomas.loc.gov | | ...
I % I Jeffrey I ...
4. 4. 4—
Для соединения, устанавливаемого Jeffrey из thomas.loc.gov, подходит первая за-
пись, а для соединения, устанавливаемого j ef f rey из whitehouse. gov - вторая.
Считается, что для данного имени пользователя, когда сервер пытается найти подхо-
дящую запись, первыми будут использоваться записи, явно хранящие имя этого пользо-
вателя. Это наиболее распространенное заблуждение. Так думать совершенно не пра-
вильно. И предыдущий пример это доказывает: первой подошедшей записью для соеди-
нения, устанавливаемого пользователем Jeffrey из thomas.loc.gov, стала не запись со
значением 'Jeffrey' в столбце User, а запись, вообще не содержащая имени пользова-
теля! В результате Jeffrey будет аутентифицирован как анонимный пользователь, хотя
он и указал имя пользователя при подсоединении.
286 Глава 4. Администрирование баз данных

Если подключиться удается, но привилегии не соответствуют ожидаемым, возможно,


вы аутентифицированы как какой-то другой пользователь. Чтобы узнать, какую учетную
запись использовал сервер для вашей аутентификации, воспользуйтесь функцией
CURRENT_USER (). Она возвратит значение в формате имя_пользователя®имя_хоста, озна-
чающем значения в столбцах User и Host из выбранной записи в таблице user. Предпо-
ложим, что Jeffrey подключается и отправляет следующий запрос:
mysql> SELECT CURRENTJJSER();
+ +
1 CURRENTJJSER () |
•f +
I @localhost |
+ +
Представленный здесь результат показывает, что выбранная в качестве подходящей
запись в таблице user имеет пустое значение в столбце User. Другими словами, сервер
воспринимает Jeffrey как анонимного пользователя.
Функция CURRENTJJSER () доступна, начиная с версии MySQL 4.O.6. Также для диагно-
стики проблем с аутентификацией можно сделать следующее: выведите таблицу user и
проведите сортировку вручную, чтобы увидеть, где было установлено первое совпадение.

4.4.6. Управление доступом, этап второй:


верификация запросов
После того как соединение установлено, сервер переходит ко второму этапу управ-
ления доступом. Для каждого поступающего через данное соединение запроса сервер
определяет, какую вы хотите выполнить операцию и затем проверяет, достаточно ли у
вас для этого привилегий. Здесь свою роль начинают играть столбцы привилегий в таб-
лицах привилегий. Привилегии могут браться из любой таблицы user, db, host,
t a b l e s p r i v или columnspriv. (В разделе 4.4.2 дается перечень столбцов каждой из
таких таблиц.)
Таблица user предоставляет привилегии, назначенные вам по глобальному принципу
и применяемые независимо от текущей базы данных. Например, если таблица user пре-
доставляет привилегию DELETE, вы сможете удалять строки из любой таблицы любой
базы данных на хосте сервера! Другими словами, привилегии в таблице user являются
привилегиями суперпользователя. Разумнее всего предоставлять привилегии в таблице
user только суперпользователям, таким как администраторы баз данных. Что касается
остальных пользователей, для них в качестве привилегий в таблице user следует остав-
лять значение ( N' и предоставлять привилегии только на более конкретных уровнях.
Можно предоставлять привилегии для определенных баз данных, таблиц или столбцов.
Таблицы db и host предоставляют привилегии на уровне базы данных. Значения в
столбцах контекста этих таблиц могут принимать следующие формы:
• Групповые символы Т и ' _ ' могут использоваться в столбцах Host и DB любой из
этих таблиц. Они имеют то же значение, что и для операций сравнения с образ-
цом, выполняемых оператором LIKE. Если вы хотите использовать любой из этих
символов буквально при предоставлении привилегий, его следует отменить с по-
мощью обратной косой черты. Например, чтобы включить символ '_' в качестве
части имени базы данных, укажите его как '\_' в операторе GRANT.
4.4. Система привилегий доступа MySQL 287

• Значение '%' в столбце Host таблицы db означает "любой хост". Пустое значение в
столбце Host таблицы db означает "для дополнительной информации просматри-
вать таблицу host" (этот процесс описывается чуть ниже в данном разделе).
• Пустое значение или значение '%' в столбце Host таблицы host означает "любой
хост".
• Пустое значение или значение '%' в столбце Db любой из таблиц означает "любая
база данных".
• Пустое значение в столбце User любой из таблиц соответствует анонимному
пользователю.
Сервер считывает и сортирует таблицы host и db, одновременно считывая таблицу
user. Сервер выполняет сортировку таблицы db по столбцам контекста Host, Db и User и
сортировку таблицы host по столбцам Host и Db. Как и в случае с таблицей user, во
время сортировки первыми размещаются наиболее точные значения, а последними -
наименее точные, и при поиске подходящих записей сервер использует первую совпав-
шую из числа найденных.
Таблицы tables_priv и columns_priv предоставляют привилегии на уровне таблиц и
столбцов. Значения в столбцах контекста этих таблиц могут принимать следующие
формы:
• Групповые символы '%' и '_' могут использоваться в столбце Host любой из этих
таблиц. Они имеют то же значение, что и для операций сравнения с образцом, вы-
полняемых оператором LIKE.
• Пустое значение или значение ' %' в любой из таблиц означает "любой хост".
• Столбцы Db, Table_name и Column_name не могут содержать групповых символов
или пустых значений в любой из таблиц.
Сервер выполняет сортировку таблиц tables_priv и columns_priv по столбцам Host,
Db и User. Она подобна сортировке в таблице db, но намного проще, поскольку только в
столбце Host могут содержаться групповые символы.
Далее описывается процесс верификации запросов. (Если вы знакомы с исходным
кодом проверки доступа, заметить, что предлагаемое здесь описание несколько отлича-
ется от используемого в коде алгоритма, будет нетрудно. Описание соответствует тому,
что на самом деле делает код и дается по-другому только с целью упростить объяснение
происходящего процесса.)
Для запросов, требующих наличия административных привилегий, таких как
SHUTDOWN или RELOAD, сервер проверяет только запись в таблице user, поскольку только в
этой таблице задаются привилегии для администрирования. Доступ предоставляется,
если данная запись разрешает запрашиваемую операцию, в противном случае в доступе
будет отказано. Например, если вы хотите выполнить mysqladmin shutdown, но ваша
запись в таблице user не предоставляет привилегии SHUTDOWN, сервер откажет в доступе
даже без проверки таблиц db или host. (Они не содержат столбца Shutdown_priv, поэто-
му проверять их нет необходимости.)
Что касается связанных с базами данных запросов (INSERT, UPDATE и так далее), сер-
вер, прежде всего, проверит глобальные привилегии (то есть привилегии суперпользова-
теля) путем просмотра записей в таблице user. Если соответствующая запись разрешает
запрашиваемую операцию, доступ будет предоставлен. Если же глобальных привилегий
288 Глава 4. Администрирование баз данных

в таблице user недостаточно, сервер перейдет к определению привилегий пользователя


на уровне баз данных, проверяя таблицы db и host:
1. Сервер ищет в таблице db запись с подходящими значениями в столбцах Host, Db
и User. Значения в столбцах Host и User сопоставляются с именем хоста и именем
пользователя MySQL, а значение в столбце Db - с именем базы данных, к которой
пользователь желает получить доступ. Если запись с соответствующими значе-
ниями в столбцах Host и User отсутствует, в доступе будет отказано.
2. Если же имеется соответствующая запись в таблице db и значение в столбце Host
не является пустым, эта запись определяет привилегии пользователя на уровне
базы данных.
3. Если же значение в столбце Host таблицы db пустое, это означает, что в таблице
host перечислены все хосты, которым должен быть разрешен доступ к базе дан-
ных. В таком случае дальнейший поиск подходящих значений в столбцах Host и
Db будет выполняться по таблице host. Если совпадения в таблице host не найде-
ны, в доступе будет отказано. В противном случае привилегии пользователя на
уровне баз данных вычисляются через операцию логического умножения (а не ло-
гического сложения!) привилегий из записей в таблицах db и host, то есть это бу-
дут привилегии со значением 'Y1 в обеих записях. (Таким способом можно сна-
чала предоставлять общие привилегии в записи таблицы db, а затем ограничивать
их для каждого хоста отдельно через записи в таблице host.)
Определив привилегии на уровне базы данных, предоставляемые записями в табли-
цах db и host, сервер добавляет их к глобальным привилегиям, предоставленным в таб-
лице user. Если получившийся результат разрешает выполнение запрашиваемой опера-
ции, доступ будет предоставлен. В противном случае сервер поочередно проверяет при-
вилегии пользователя на уровне таблиц и столбцов в таблицах tables_priv и
colurans_priv, добавляет их к остальным привилегиям пользователя и, в зависимости от
получившегося результата, либо разрешает, либо запрещает доступ.
На языке булевской логики приведенное выше описание вычисления привилегий
пользователя будет выглядеть так:
глобальные привилегии
OR {привилегии базы данных AND привилегии хоста)
OR привилегии таблицы
OR привилегии столбца
Если изначально определено, что глобальных привилегий в записи таблицы user не
достаточно для выполнения запрашиваемой операции, причина, по которой сервер затем
начинает добавлять их к привилегиям на уровне баз данных, таблиц и столбцов, не
вполне очевидна. А заключается она в том, что данный запрос может требовать наличия
более чем одного типа привилегий. Например, чтобы выполнить оператор INSERT
INTO.. .SELECT, понадобятся привилегии INSERT и SELECT. Одна из них может предостав-
ляться записью в таблице user, а другая в это же время - записью в таблице db. В таком
случае имеются все необходимые для выполнения запроса привилегии, но сервер не мо-
жет знать об этом, проверив только одну из таблиц, ему необходимо скомбинировать
привилегии, предоставляемые записями в обеих таблицах.
Операторы GRANT и REVOKE никак не действуют на таблицу host, поэтому она и не ис-
пользуется в большинстве установок MySQL. При внесении изменений непосредствен-
4.4. Система привилегий доступа MySQL 289

но, ее можно будет использовать и для специальных целей, как, например, для поддерж-
ки списка защищенных серверов. Так, в ТсХ таблица host содержит список всех машин
локальной сети. Им предоставлены все привилегии.
Также таблицу host можно использовать для указания небезопасных хостов. Предпо-
ложим, машина public.your.domain находится в общедоступной области, которую вы
не считаете безопасной. С помощью записей в таблице host, подобным тем, которые
представлены ниже, появляется возможность разрешить доступ абсолютно всем хостам,
кроме именно этой небезопасной машины:

I Host | Db | . . .
+ + +-
I public.your.domain | % I . . . (все привилегии установлены в ' N')
I %. your, domain | % I . . . (все привилегии установлены в ' Y')

Естественно, всегда следует тестировать записи в таблицах привилегий (например, с


помощью SHOW GRANTS или mysqlaccess), дабы убедиться в том, что привилегии доступа
установлены именно так, как вы думаете.

4.4.7. Когда изменения в привилегиях вступают в силу


При запуске mysqld содержимое всех таблиц привилегий считывается и заносится в
память, с этого момента все привилегии вступают в силу и управляют доступом к серверу.
Когда сервер загружает таблицы привилегий повторно, это отражается на привилеги-
ях для существующих клиентских соединений следующим образом:
• Изменения в привилегиях на уровне таблиц и столбцов вступают в силу при сле-
дующем запросе клиента.
• Изменения на уровне баз данных вступают в силу при следующем использовании
оператора USE имя_базы_данных.
• Изменения в глобальных привилегиях и паролях вступают в силу при следующем
подключении клиента.
Если изменения вносятся в таблицы привилегий с помощью GRANT, REVOKE или SET
PASSWORD, сервер замечает их и незамедлительно снова перезагружает таблицы в память.
Если изменения вносятся непосредственно, с помощью операторов INSERT, UPDATE
или DELETE, они вступают в силу только после перезапуска сервера или только тогда,
когда серверу будет указано, что таблицы должны быть перезагружены. Чтобы переза-
грузить таблицы привилегий вручную, используйте оператор FLUSH PRIVILEGES либо
команду mysqladmin flush-privileges или mysqladmin reload.
Если внести изменения непосредственно, но не перезагрузить таблицы привилегий,
изменения вступят в силу только после перезапуска сервера, так что не удивляйтесь, ес-
ли сразу не увидите результата своих действий!

4.4.8. Причины появления ошибок отказа в доступе


(Access denied)
Если при попытке подключиться к серверу MySQL возникают проблемы, воспользуйтесь
представленным ниже списком действий, которые можно предпринять для их решения:
290 Глава 4. Администрирование баз данных

• Убедитесь, что сервер функционирует. Если это не так, подключиться к нему


нельзя. Например, причиной того, что при попытке подсоединиться к серверу по-
является одно из следующих сообщений, может быть именно отсутствие активно-
сти сервера:
shell> mysql
ERROR 2003: Can't connect to MySQL server on 'host_name' (111)
shell> mysql
ERROR 2002: Can't connect to local MySQL server through socket
'/tmp/mysql.sock1 (111)
Еще одной причиной этому может служить то, что сервер работает, но при по-
пытке подключиться используются TCP/IP-порт, именованный канал или файл
сокета Unix, отличные от тех, которые прослушиваются сервером. Чтобы испра-
вить такую ошибку, при вызове клиентской программы задайте опцию —port и
укажите корректный порт, или опцию -socket и задайте правильный именован-
ный канал или сокет Unix.
• Таблицы привилегий должны быть корректно установлены, так чтобы сервер мог
использовать их для управления доступом. При установке MySQL из бинарного
дистрибутива в Windows или дистрибутива RPM в Linux, во время процесса уста-
новки создается база данных mysql, содержащая таблицы привилегий. При других
типах установки MySQL создавать таблицы привилегий необходимо вручную, за-
пустив сценарий mysql_install_db. См. раздел 2.4.2.
Единственный способ определить, есть ли необходимость в инициализации таб-
лиц привилегий, это проверить наличие каталога mysql в каталоге данных. (Ката-
лог данных обычно имеет имя data или var и находится в каталоге установки
MySQL). Убедитесь, что в каталоге баз данных mysql присутствует файл с именем
user.MYD. Если его там нет, запустите сценарий mysql_install_db. После запуска
сценария и сервера протестируйте исходные привилегии с помощью следующей
команды:
shell> mysql -u root test
Подключение к серверу должно пройти без ошибок.
• После новой установки необходимо подключиться к серверу, установить пользо-
вателей и права доступа для них.
shell> mysql -u root mysql
Сервер должен разрешить подсоединение, поскольку первоначально MySQL-
пользователь root не имеет пароля. Но это также представляет определенный
риск для безопасности системы, поэтому во время настройки учетных записей
других пользователей MySQL следует позаботиться и об установке пароля для
учетной записи root. Информацию по установке исходных паролей можно найти
в разделе 2.4.5.
• Запускался ли сценарий mysql_f ix_privilege_tables после того, как была прове-
дена модернизация существующей установки MySQL до более новой версии? Ес-
ли нет, это необходимо сделать. Структура таблиц привилегий порой изменяется,
когда добавляются новые функциональные возможности, поэтому после модерни-
зации следует обязательно убедиться, что ваши таблицы имеют актуальную
структуру. Для более подробной информации см. раздел 2.5.8.
4.4. Система привилегий доступа MySQL 291

• Если клиентская программа получает следующее сообщение об ошибке при по-


пытке подсоединения к серверу, это значит, что сервер ожидает ввода паролей
более нового, нежели доступен клиенту, формата:
shell> mysql
Client does not support authentication protocol requested
by server; consider upgrading MySQL client
Информация о том, что можно сделать в таких случаях, находится в разделах 4.4.9
иА.2.3.
• Если при попытке подключиться к серверу в качестве привилегированного (root)
пользователя, вы получаете следующую ошибку, это значит, что в таблице user
нет записи со значением 'root 1 в столбце User, и сервер не может преобразовать
имя хоста для вашего клиента:
Access denied for user: lf@'unknown' to database mysql
В таком случае потребуется перезапустить сервер с опцией —skip-grant-tables
и отредактировать файл /etc/hosts или \windows\hosts, добавив в него запись
для вашего хоста.
• Не забывайте о том, что клиентские программы будут использовать параметры
соединения, заданные в файлах опций или переменных окружения. Если отправ-
ляемые клиентской программой параметры соединения по умолчанию (когда в
командной строке они не указываются) кажутся неверными, проверьте файлы
конфигурации и все остальные используемые файлы опций. Например, если при
запуске сервера без опций, вы получаете ошибку Access denied ("В доступе отка-
зано"), убедитесь, что ни в одном из файлов опций не был указан старый пароль!
Можно отменить использование файлов опций через клиентскую программу, вы-
звав ее с опцией --no-defaults, например:
shell> mysqladmin —no-defaults -u root version
Используемые клиентами файлы опций перечислены в разделе 3.3.2. Переменные
окружения представлены в приложении Б.
• Если вы получаете следующую ошибку, это означает, что используется некор-
ректный пароль для root:
shell> mysqladmin -u root -pxxxx ver
Access denied for user: 'root'@'localhost' (Using password: YES)
Если подобная ошибка появляется даже тогда, когда пароль не был задан, это зна-
чит, что в одном из файлов опций указан некорректный пароль. Попробуйте вос-
пользоваться опцией --no-defaults, как описано в предыдущем пункте.
Информация об изменении паролей находится в разделе 4.5.5.
Если Вы забыли или потеряли пароль для root, можете перезапустить mysqld с
опцией —skipgrant-tables, чтобы изменить пароль. См. раздел А.4.1.
• При изменении пароля посредством SET PASSWORD, INSERT или UPDATE необходимо
его зашифровать с использованием функции PASSWORD(). Если для указанных
операторов не использовать функцию PASSWORD(), пароль работать не будет. На-
пример, следующий оператор устанавливает пароль, но не шифрует его, поэтому
впоследствии пользователь подключиться к серверу не сможет:
292 Глава 4. Администрирование баз данных

1
mysql> SET PASSWORD FOR ' a b e ' @ ' и м я _ х о с т а ' = ' e a g l e ;
Вместо этого пароль нужно устанавливать так:
mysql> SET PASSWORD FOR 'abe'@'имя_хоста' = PASSWORD('eagle');
При задании пароля с помощью оператора GRANT или команды mysqladmin
password указывать функцию PASSWORD не обязательно, поскольку в таком случае
она используется для шифрования пароля автоматически. См. раздел 4.5.5.
• localhost является синонимом имени вашего локального хоста, а также исполь-
зуемым по умолчанию именем хоста, к которому будут пытаться подключиться
клиенты, если хост явно задан не был. Однако соединения с localhost в системах
Unix работать не будут, если используется версия MySQL, предшествующая
3.23.27, и потоки MIT-pthreads: соединения с localhost устанавливаются с помо-
щью файлов сокетов Unix, которые в то время потоки MIT-pthreads не поддержи-
вали.
Во избежание этой проблемы на таких системах с помощью опции --host=
127.0.0.1 явно задавайте имя хоста. В результате будет установлено TCP/IP-
соединение с локальным сервером mysqld. Установить TCP/IP-соединение можно
и с помощью опции —host, в которой необходимо указать реальное имя локаль-
ного хоста. В этом случае имя хоста должно быть задано в записи таблицы user
на хосте сервера, даже если клиентская программа и сервер запускаются на одном
и том же хосте.
• Если ошибка Access denied возникает, когда вы подключаетесь к базе данных с
помощью mysql -u имя_пользователя, скорее всего, проблема заключается в таб-
лице user. Проверить это можно с помощью команды mysql -u root mysql ИЛИ
следующего SQL-оператора:
mysql> SELECT * FROM user;
Результат должен включать запись, значения в столбцах Host и User которой со-
ответствуют имени хоста вашего компьютера и вашему имени пользователя
MySQL.
• Сообщение об ошибке Access denied будет содержать следующую информацию:
под каким именем вы пытаетесь войти в систему, имя хоста клиента, с которого
вы пытаетесь подсоединиться, и вводился ли вами пароль. Обычно в таблице user
должна присутствовать только одна запись, в точности соответствующая имени
хоста и имени пользователя, которые указаны в сообщении об ошибке. Например,
"Using password: NO" в сообщении об ошибке будет означать, что вы пытались
войти в систему без указания пароля.
• Если при попытке подключиться с другого, не того, на котором работает сервер
MySQL, хоста возникает приведенная ниже ошибка, это значит, что в таблице
user отсутствует строка со значением в столбце Host, которое соответствует име-
ни хоста клиента.
Host . . . is not allowed to connect to this MySQL server
Хосту . . . не разрешено подключаться к этому серверу MySQL
Устранить эту проблему можно путем установки для учетной записи комбинации
из числа используемых для подключения имени клиентского хоста и имени поль-
зователя.
4.4. Система привилегий доступа MySQL 293

Если IP-адрес или имя хоста машины, к которой выполняется подключение, не


известно, в таблицу user необходимо добавить запись со значением ' % ' в столбце
Host и перезапустить mysqld с опцией -log на машине сервера. После подключе-
ния с клиентской машины в журнале регистрации MySQL будет содержаться ин-
формация об этом самом подключении. (Затем потребуется заменить значение ' %'
в записи таблицы user на реальное имя хоста, появившееся в журнале. В против-
ном случае ваша система не будет безопасной, поскольку что она разрешает со-
единения с любого хоста для данного имени пользователя.)
В среде Linux еще одна причина возникновения такой ошибки может заключаться
и в том, что бинарная версия MySQL скомпилирована с другой, а не той, что ис-
пользуется, версией библиотеки glibc. В таком случае потребуется либо обновить
версию операционной системы, либо версию glibc, или же загрузить исходный
дистрибутив версии MySQL и скомпилировать его самостоятельно. Обычно уста-
новить и скомпилировать исходный RPM-модуль также не составляет особого
труда, поэтому серьезной проблемой это не является.
• Если при попытке подключиться вы указываете имя хоста, но получаете сообще-
ние об ошибке, где имя хоста не отображено или представляет собой IP-адрес, это
значит, что ошибка возникла, когда MySQL пытался преобразовать IP-адрес в имя
клиентского хоста:
shell> mysqladmin -u root -pxxxx -h some-hostname ver
Access denied for user: ' r o o t ' G 1 1 (Using password: YES)
Это говорит о проблеме с системой DNS. Для разрешения этой проблемы понадо-
бится выполнить mysqladmin flush-hosts, чтобы сбросить внутренний кэш имен
хостов DNS. См. раздел 6.5.5.
Ниже представлены основные варианты решения этой проблемы:
• Попробуйте выяснить, что именно не так с сервером DNS, и устранить про-
блему.
• В таблицах привилегий MySQL лучше указывать IP-адреса, а не имена хостов.
• Добавьте запись для имени машины клиента в каталог /etc/hosts.
• Запустите mysqld с опцией --skip-name-resolve.
• Запустите mysqld с опцией —skip-host-cache.
• В среде Unix, если сервер и клиент работают на одной и той же машине, под-
ключайтесь к localhost. Для таких соединений используется файл сокета
Unix, а не TCP/IP.
• В среде Windows, если сервер и клиент работают на одной и той же машине, а
также если сервер поддерживает соединения через именованные каналы, под-
ключайтесь через имя хоста . (точка). Такие соединения используют имено-
ванные каналы, а не TCP/IP.
• Если mysql -u root t e s t работает, а вот при выполнении mysql -h имя_хоста
-u root (где имя_хоста - это реальное имя локального хоста) возникает ошибка
Access denied, возможно, в таблице user неправильно указано имя вашего хоста.
Основная проблема здесь заключается в том, что значение в столбце Host табли-
цы user соответствует неуточненному имени хоста, в то время как операции пре-
образования имен, выполняемые вашей системой, возвращают полностью уточ-
294 Глава 4. Администрирование баз данных

ненное имя домена (или наоборот). Например, если в таблице user имеется запись
со значением ' tcx 1 в качестве имени хоста, но система DNS передает MySQL имя
хоста ' tcx. subnet. se', эта запись работать не будет. Попробуйте добавить в таб-
лицу user запись, в которой для имени хоста в столбце Host указан IP-адрес. (Или
же в таблицу user можно добавить запись, значение в столбце Host которой будет
содержать групповой символ, например, 'tcx.% 1 . Однако, использовать имена
хостов, заканчивающиеся на '%', небезопасно, и поэтому не рекомендуется.)
• Если команда mysql -u имя_пользователя t e s t работает, а команда mysql -и
имя_пользователя имя_другой_базы_данных - нет, значит, данному пользователю
не был предоставлен доступ к базе данных имя_другой_базы_данных.
• Если команда mysql -u имя_пользователя на хосте сервера работает, а на удален-
ном хосте клиента нет, значит, для данного имени пользователя не был разрешен
доступ к серверу с удаленного хоста.
• Если причину появления ошибки Access denied выяснить никак не получается,
удалите из таблицы user все записи со значениями в столбце Host, содержащими
групповые символы (т.е. '%' или '_'). Наиболее распространенная ошибка состоит
в том, что после вставки новой записи со значением '%' в столбце Host и 'пользо-
ватель' в столбце User пользователь считает, что это позволит ему задавать
localhost для подключения с той же машины. Это не так, потому что привиле-
гии по умолчанию включают запись со значением 'localhost' в столбце Host и
значением ' ' в столбце User. Поскольку значение localhost является более точ-
ным, чем '%', то именно запись с таким значением, а не добавленная новая запись
будет использоваться при подключении к localhost! Правильным будет добавить
еще одну запись со значениями 'localhost' в столбце Host и 'пользователь' в
столбце User, или же вообще удалить запись со значением 'localhost' в столбце
Host и значением ' ' в столбце User. После удаления не забудьте выполнить опе-
ратор FLUSH PRIVILEGES, чтобы перезагрузить таблицы привилегий.
• Если возникает следующая ошибка, возможно имеют место проблемы с таблицей
db или таблицей host:
Access to database denied
В доступе к базе данных отказано
Если выбранная из таблицы db запись содержит пустое значение в столбце Host,
убедитесь, что в таблице host имеется, по крайней мере, одна или несколько со-
ответствующих записей, указывающих, к каким хостам относится запись из таб-
лицы db.
• Если вы подключаетесь к серверу MySQL без проблем, но сообщение Access
denied появляется каждый раз, когда используются операторы SELECT.. .INTO
OUTFILE и LOAD DATA INFILE, значит, ваша запись в таблице user не имеет приви-
легии FILE.
• Если изменения вносятся в таблицы привилегий непосредственно (с помощью
операторов INSERT, UPDATE и DELETE) и при этом вроде как игнорируются, не за-
будьте о том, что необходимо выполнить оператор FLUSH PRIVILEGES или же ко-
манду flush-privileges, чтобы сервер осуществил повторное считывание таблиц
привилегий. В противном случае изменения вступят в силу только после переза-
4.4. Система привилегий доступа MySQL 295

пуска сервера. Также помните, что после изменения пароля для root с помощью
команды UPDATE задавать новый пароль до тех пор, пока не будет очищен список
привилегий, не нужно, поскольку до этого времени сервер не будет знать о том,
что пароль был изменен.
• Если вам кажется, что ваши привилегии изменились непосредственно во время
сеанса, скорее всего, их изменил администратор MySQL. Перезагрузка таблиц
привилегий отразится не только на соединениях клиентов, но и на существующих
соединениях, как описано в разделе 4.4.7.
• Если возникают проблемы с доступом при использовании программ Perl, PHP,
Python или ODBC, попробуйте подсоединиться к серверу через mysql -u
имя_пользователя имя_базы_данных ИЛИ mysql -и имя_пользователя -рпароль
имя_базы_данных. Если установить соединение с помощью клиента mysql удается,
значит, проблема связана с вашей программой, а не с привилегиями доступа.
(Пробел между -р и паролем не ставится; для задания пароля можно также ис-
пользовать синтаксис —passworс1=пароль. Если применяется только опция -р,
MySQL запросит ввод пароля.)
• Для целей тестирования запустите сервер mysqld с опцией --skip-grant-tables.
В этом случае можно будет внести изменения в таблицы привилегий MySQL и
воспользоваться сценарием mysqlaccess, чтобы проверить, приводят ли они к
ожидаемым результатам. Если результаты изменений удовлетворительные, вы-
полните команду mysqladmin flush-privileges, чтобы сервер начал использо-
вать новые таблицы привилегий. (Перезагрузка таблиц привилегий перекрывает
опцию —skip-grant-tables, что позволяет заставить сервер начать снова исполь-
зовать таблицы привилегий без остановки его работы и перезапуска.)
• Если ничего не получается, запустите сервер mysqld с опцией отладки (например,
—debug=d,general,query). Будут выведены данные хоста и пользователя о не-
удачных попытках соединения с сервером, а также информация о каждой коман-
де, которая была использована.
• При наличии любых других проблем с таблицами привилегий MySQL, которые,
по вашему мнению, необходимо передать в список рассылки, всегда предостав-
ляйте дамп таблиц привилегий MySQL. Получить такие данные можно с помо-
щью команды mysqldump mysql, а отправить отчет о проблеме - с помощью сце-
нария mysqlbug. См. раздел 1.7.1.3. В некоторых случаях для выполнения
mysqldump может понадобиться перезапустить сервер.

4.4.9 Хеширование паролей в MySQL 4.1


Все учетные записи пользователей MySQL представлены в таблице user базы дан-
ных mysql. Для каждой из них назначен пароль, однако в столбце Password таблицы
User хранится не пароль в виде открытого текста, а его хеш-значение. Хеш-значения
паролей вычисляются с помощью функции PASSWORD ().
MySQL использует пароли на двух этапах клиент-серверного взаимодействия:
• Когда клиент пытается подключиться к серверу, он проходит первую стадию ау-
тентификации, когда он должен ввести пароль, хеш-значение которого соответст-
вует хеш-значению из таблицы user для выбранной клиентом учетной записи.
296 Глава 4. Администрирование баз данных

• После подключения клиент, имея достаточно привилегий, может устанавливать


или изменять хеш-значения паролей для учетных записей, представленных в таб-
лице user. И делать он это может с помощью функции PASSWORD (), чтобы генери-
ровать хеш-значение пароля, или с помощью операторов GRANT или SET PASSWORD.
Другими словами, сервер использует хеш-значения во время аутентификации, когда
клиент сначала только пытается подключиться. Сервер генерирует хеш-значения, если
уже подключившийся клиент вызывает функцию PASSWORD () или использует операторы
GRANT или SET PASSWORD, чтобы установить или изменить пароль.
Алгоритм хеширования паролей в MySQL 4.1 был усовершенствован с целью обес-
печения более высокой степени безопасности и сокращения риска перехвата паролей.
Однако работать с ним могут только клиенты и сервер версии 4.1, что приводит к воз-
никновению ряда проблем с совместимостью. Клиент, использующий версию 4.1, может
подключаться к серверу более ранней версии (до 4.1), поскольку клиент понимает как
старые, так и новые алгоритмы хеширования паролей. А вот клиент, использующий вер-
сию, предшествующую 4.1, может столкнуться с трудностями при подключении к сер-
веру версии 4.1. Например, клиент mysql версии 4.0 при попытке подсоединиться к сер-
веру версии 4.1 может получить следующее сообщение об ошибке:
shell> mysql -h localhost -u root
Client does not support authentication protocol requested
by server; consider upgrading MySQL client
Клиент не поддерживает протокол аутентификации, требуемый сервером;
рекомендуется обновление версии клиента MySQL

Ниже предлагается описание различий между старым и новым алгоритмом паролей и


что нужно делать, если выполняется модернизация сервера до версии 4.1 и при этом не-
обходима поддержка обратной совместимости с клиентами, использующими более ран-
ние (до 4.1) версии. Дополнительную информацию можно найти в разделе А.2.3.
; На заметку!
В этом описании сопоставляются процессы хеширования паролей в версии 4.1 с процессами в
{
версиях, предшествующих 4.1, но фактически здесь уже подразумевается версия 4.1.1. Версию
' ' MySQL 4.1.0 можно назвать "лишней", поскольку используемый в ней алгоритм совсем незначи-
\ тельно отличается от алгоритма в версиях 4.1.1 и выше. Отличия версии 4.1.0 от более ранних
'(' версий более подробно описаны в разделе 4.4.9.2.

В версиях, предшествующих MySQL 4.1, хеш-значения паролей, вычисляемые с по-


мощью функции PASSWORD (), имеют длину 16 байт и выглядят приблизительно так:
mysql> SELECT PASSWORD('mypass');

PASSWORD('mypass') |
+
6f8cll4b58f2ce9e |

Столбец Password таблицы user (в котором хранятся эти хеш-значения) в версиях до


MySQL 4.1 также имеет длину 16 байт.
Начиная с MySQL 4.1, функция PASSWORD () изменена и выдает более длинное хеш-
значение, длина которого составляет 41 байт:
4.4. Система привилегий доступа MySQL 297

mysql> SELECT PASSWORD('mypass');


+ +

I PASSWORD!'mypass1) |

I *43c8aa34cdc98eddd3delfe9a9c2c2a9f92bb2098d75 |
+ +

Соответственно, длина столбца Password таблицы user также должна равняться 41


байту, чтобы можно было хранить такие значения:
• Если устанавливается новая версия, MySQL 4.1, длина столбца Password составит
41 байт автоматически.
• Если проводилась модернизация с более старой версии MySQL до версии 4.1, не-
обходимо запустить сценарий mysql_fix_privilege_tables, чтобы увеличить
длину столбца Password с 16 до 41 байта. (Сценарий не изменяет существующие
значения паролей, длина которых по-прежнему будет составлять 16 байт.)
Расширенный столбец Password может хранить хеш-значения паролей как старого, так
и нового формата. Формат любого хеш-значения можно определить двумя способами:
• Явный отличительный признак - это длина хеш-значения (16 байт или 41 байт).
• Второй отличительный признак: хеш-значения паролей в новом формате всегда на-
чинаются с символа '*', в то время как хеш-значения в старом формате - никогда.
Более длинный формат хеш-значений паролей обладает лучшими криптографиче-
скими свойствами, и аутентификация клиента по более длинным хеш-значениям безо-
паснее, чем аутентификация, во время которой используются старые короткие хеш-
значения.
Различия между короткими и длинными хеш-значениями паролей имеют непосред-
ственное отношение и к тому, как сервер будет использовать пароли во время аутенти-
фикации, и к тому, как он будет генерировать хеш-значения паролей для уже подклю-
чившихся клиентов, которые выполняют операции замены паролей.
То, как сервер будет использовать хеш-значения паролей во время аутентификации,
зависит от размера столбца Password:
• Если столбец небольшой (короткий), будет использоваться только аутентифика-
ция по коротким хеш-значениям.
• Если столбец большой (длинный), он может вмещать как короткие, так и длинные
хеш-значения, поэтому сервер может использовать любой формат:
• Клиенты, использующие версию, предшествующую 4.1, смогут подключаться
к серверу, однако поскольку им знаком только старый алгоритм, аутентифика-
ция будет возможна только для учетных записей с короткими хеш-значениями
паролей.
• Клиенты, использующие версию 4.1, могут проводить аутентификацию для
учетных записей как с короткими, так и с длинными хеш-значениями.
Что касается учетных записей с короткими хеш-значениями, процесс аутентифика-
ции фактически немного более безопасен для клиентов версии 4.1, чем для клиентов
более старых версий. В целом, степень безопасности при аутентификации тех или иных
клиентов представлена ниже, в порядке возрастания:
• Клиенты версий, предшествующих 4.1, выполняющие аутентификацию для учет-
ных записей с короткими хеш-значениями паролей.
298 Глава 4. Администрирование баз данных

• Клиенты версии 4.1, выполняющие аутентификацию для учетных записей с ко-


роткими хеш-значениями паролей.
• Клиенты версии 4.1, выполняющие аутентификацию для учетных записей с длин-
ными хеш-значениями паролей.
То, как сервер генерирует хеш-значения паролей для уже подключившихся клиентов,
зависит от размера столбца Password и опции —old-passwords. Сервер версии 4.1 гене-
рирует длинные хеш-хначения, только если выполнены следующие условия: размер
столбца Password достаточно большой, чтобы вместить длинные значения, и опция
—old-password не использовалась. Эти условия проверяются следующим образом:
• Размер столбца Password должен быть достаточно большим, чтобы вмещать
длинные хеш-значения (41 байт). Если размер столбца не изменен и по-прежнему
равен 16 байтам (это размер столбца в версиях ниже, чем 4.1.), сервер видит, что
длинные значения в столбце не помещаются, и когда клиент выполняет операции
по изменению пароля с помощью функции PASSWORD () или операторов GRANT и
SET PASSWORD, он генерирует только короткие хеш-значения. Такое случается, ес-
ли вы провели модернизацию до версии 4.1, но еще не запускали сценарий
mysql_f ix_privilege_tables, который увеличивает размер столбца Password.
• Большой размер столбца Password позволяет хранить как короткие, так и длинные
хеш-значения. В этом случае при использовании функции PASSWORD () или опера-
торов GRANT и SET PASSWORD будут генерироваться длинные хеш-значения, если
только сервер не был запущен с опцией --old-passwords, которая вместо этого
заставляет сервер генерировать короткие хеш-значения паролей.
Опция —old-passwords предназначена для поддержки обратной совместимости с
клиентами, использующими версии ниже 4.1, в тех случаях, когда иначе сервер генери-
ровал бы длинные хеш-значения паролей. Данная опция не влияет на аутентификацию
(клиенты версии 4.1 по-прежнему могут использовать учетные записи с длинными хеш-
значениями паролей), но она запрещает создавать длинные хеш-значения в таблице user
при операциях по изменению паролей. Случись такое, клиенты версии ниже 4.1 не смог-
ли бы больше использовать такую учетную запись. Если опция —old-passwords не ука-
зывается, возможен следующий нежелательный сценарий:
• Клиент старой версии подключается к учетной записи с коротким хеш-значением
пароля.
• Клиент изменяет свой пароль. Если опция --old-passwords не используется, это
приводит к появлению у учетной записи длинного хеш-значения пароля.
• Когда клиент старой версии в следующий раз попытается подключиться к учет-
ной записи, он этого сделать не сможет, потому что теперь учетная запись имеет
длинное хеш-значение пароля, требующее во время аутентификации применения
нового алгоритма хеширования. (Как только у учетной записи появляется длинное
хеш-значение пароля, пытаться получить доступ к ней смогут только клиенты
версии 4.1, поскольку клиенты более ранних версий не распознают хеш-значений,
которые являются длинными.)
Данный сценарий иллюстрирует, что при необходимости в поддержке клиентов ста-
рых (до 4.1) версий, опасно запускать сервер версии 4.1 без опции —old-passwords. При
запуске сервера с опцией --old-passwords операции по изменению пароля не будут ге-
нерировать длинные хеш-значения паролей и, таким образом, не приведут к тому, что
4.4. Система привилегий доступа MySQL 299

учетные записи станут недоступными для клиентов старых версий. (Такие клиенты не
смогут случайно сами себя заблокировать, изменив пароль и, тем самым, получив длин-
ные хеш-значения.)
Недостатком применения опции —old-passwords является то, что любые создавае-
мые или изменяемые вами пароли будут использовать только короткие хеш-значения
(это касается даже клиентов версии 4.1). Таким образом, дополнительная степень безо-
пасности, предоставляемая длинными хеш-значениями паролей, теряется. Если требует-
ся создать учетную запись с длинным хеш-значением, (например, для использования
клиентами версии 4.1), это следует делать тогда, когда сервер запускается без опции
—old-passwords.
При работе с сервером версии 4.1 возможны следующие сценарии:
Сценарий 1. Размер столбца Password в таблице user маленький.
• В столбце Password могут храниться только короткие хеш-значения.
• Во время аутентификации клиента сервер использует только короткие хеш-
значения.
• Уже подключившиеся клиенты в операциях по генерированию хеш-значений па-
ролей с применением PASSWORD(), GRANT или SET PASSWORD смогут использовать
исключительно короткие хеш-значения. При любом изменении в пароле учетной
записи ее хеш-значение пароля все равно будет коротким.
• Использовать опцию —old-password можно, но не нужно, поскольку если размер
столбца Password маленький, сервер в любом случае будет автоматически генери-
ровать только короткие хеш-значения паролей.
Сценарий 2. Размер столбца Password большой; сервер запускался без опции
—old-password.
• В столбце Password могут храниться как короткие, так и длинные хеш-значения.
• Клиенты версии 4.1 могут проводить аутентификацию для учетных записей как с
короткими, так и с длинными хеш-значениями.
• Клиенты старых (до 4.1) версий могут проводить аутентификацию только для
учетных записей с короткими хеш-значениями.
• Уже подключившиеся клиенты в операциях по генерированию хеш-значений па-
ролей с применением PASSWORD!), GRANT или SET PASSWORD смогут использовать
исключительно длинные хеш-значения. При любом изменении в пароле учетной
записи ее хеш-значение пароля будет длинным.
Как упоминалось ранее, опасность при таком сценарии состоит в том, что учетные
записи с коротким хеш-значением паролей могут стать недоступными для клиентов вер-
сий, предшествующих 4.1. Изменения, вносимые в пароли таких учетных записей с по-
мощью функции PASSWORD () или операторов GRANT и SET PASSWORD, приводят к тому, что
учетная запись получает длинное хеш-значение пароля. И с этого момента ни один кли-
ент старой (до 4.1) версии не сможет получить к ней доступ до тех пор, пока он не будет
модернизирован до версии 4.1.
Чтобы решить эту проблему, можно изменять пароль особым способом. Например,
обычно для изменения пароля учетной записи оператор SET PASSWORD используется сле-
дующим образом:
1
mysql> SET PASSWORD FOR 'пользователь'@'хост = PASSWORD('mypass');
300 Глава 4. Администрирование баз данных

Чтобы изменить пароль и при этом создать короткое хеш-значение, вместо оператора
SET PASSWORD используйте функцию OLD_PASSWORD ():
mysql> SET PASSWORD FOR 'пользователь1@!хост' = OLD_PASSWORD('mypass');
Функция OLD_PASSWORD() полезна в ситуациях, когда вы явно хотите генерировать
короткое хеш-значение.
Сценарий 3. Размер столбца Password большой; сервер запускался с опцией
—old-passwords.
• В столбце Password могут храниться как короткие, так и длинные хеш-значения.
• Клиенты версии 4.1 могут проводить аутентификацию для учетных записей как с
короткими, так и с длинными хеш-значениями (однако обратите внимание на то,
что создавать длинные хеш-значения можно только тогда, когда сервер запускал-
ся без опции —old-passwords).
• Клиенты старых (до 4.1) версий могут проводить аутентификацию только для
учетных записей с короткими хеш-значениями.
• Уже подключившиеся клиенты в операциях по генерированию хеш-значений па-
ролей с применением PASSWORD(), GRANT или SET PASSWORD смогут использовать
исключительно короткие хеш-значения. При любом изменении в пароле учетной
записи ее хеш-значение пароля все равно будет коротким.
При таком сценарии нельзя создать учетные записи с длинными хеш-значениями па-
ролей, потому что опция —old-passwords запрещает генерирование длинных хеш-
значений. Кроме того, даже если создать учетную запись с длинным хеш-значением до
применения опции —old-passwords, изменения ее пароля во время действия этой опции
приведет к тому, что она получит короткий пароль, потеряв тем самым все преимущест-
ва по безопасности, предоставляемые более длинными хеш-значениями.
Негативные аспекты предложенных сценариев могут быть резюмированы следую-
щим образом:
При сценарии 1 нельзя воспользоваться преимуществами длинных хеш-значений, ко-
торые обеспечивают более безопасную аутентификацию.
При сценарии 2 учетные записи с короткими хеш-значениями становятся недоступ-
ными для клиентов старых (до 4.1) версий, если во время изменения их паролей не была
явно использована функция OLD_PASSWORD ().
При сценарии 3 опция —old-passwords не допускает того, чтобы учетные записи с
короткими хеш-значениями становились недоступными, но операции по изменению па-
ролей приводят к тому, что учетные записи с длинными хеш-значениями снова получа-
ют короткие хеш-значения, и сделать их опять длинными нельзя до тех пор, пока дейст-
вует опция --old-passwords.

4.4.9.1. Последствия внесения изменений в алгоритм хеширования паролей


для прикладных программ
Модернизация до версии MySQL 4.1 может привести к возникновению проблем с со-
вместимостью приложений, которые используют функцию PASSWORD () для генерирова-
ния паролей в своих собственных целях. На самом деле приложения так делать не долж-
ны, поскольку функция PASSWORD!) предназначена непосредственно для управления па-
ролями учетных записей MySQL. Но все равно некоторые из них используют функцию
PASSWORD () в своих личных целях.
4.5. Управление учетными записями пользователей MySQL 301

Если вы провели модернизацию до версии 4.1 и сервер работает в режиме генериро-


вания длинных хеш-значений паролей, приложение, использующее функцию PASSWORD ()
для создания своих собственных паролей, перестанет функционировать. Рекомендуе-
мый способ действий - модифицировать приложение таким образом, чтобы для созда-
ния хешированных значений им использовалась какая-нибудь другая функция, напри-
мер, SHA1O или MD5(). Если это невозможно, попробуйте применить функцию
OLD_PASSWORD (), предназначенную для генерирования коротких хеш-значений старо-
го формата. Но не забывайте о том, что может наступить день, когда функция
OLD_PASSWORD () больше поддерживаться не будет.
Если сервер работает в режиме генерирования коротких хеш-значений, функция
OLD_PASSWORD () доступна, но ее работа эквивалентна работе функции PASSWORD ().

4.4.9.2. Хеширование паролей в MySQL 4.1.0


Хеширование паролей в MySQL 4.1.0 отличается от хеширования в версии 4.1.1 и
выше и эти отличия следующие:
• Размер хеш-значений паролей равен 45 байт, а не 41 байту.
• Функция PASSWORD () является неповторяющейся, то есть при данном аргументе х
последовательные вызовы PASSWORD (x) генерируют разные пароли.
Эти отличия делают аутентификацию в версии MySQL 4.1.0 не совместимой с аутен-
тификацией в последующих версиях. В случае модернизации до версии MySQL 4.1.0
рекомендуется как можно быстрее провести модернизацию до более новой версии. По-
сле этого необходимо переназначить все длинные пароли в таблице user так, чтобы их
формат соответствовал 41 байту.

45. Управление учетными записями


пользователей MySQL
В настоящем разделе описано, как произвести установку учетных записей для клиен-
тов сервера MySQL. Здесь обсуждаются следующие вопросы:
• Значение используемых в MySQL имен учетных записей и паролей в сравнении с
именами и паролями, используемыми операционной системой.
• Как устанавливать новые и удалять существующие учетные записи.
• Как изменять пароли.
• Правила безопасного использования паролей.
• Как использовать безопасные соединения с помощью SSL.

4.5.1. Имена пользователей и пароли в MySQL


Учетная запись MySQL определяется именем пользователя и именем хоста (или хос-
тов) клиента, с которого пользователь может подключиться к серверу. Также учетная
запись имеет пароль. Существует несколько различий между тем, как имена пользовате-
лей и пароли используются MySQL, и тем, как они используются вашей операционной
системой:
• Имена пользователей, используемые MySQL для аутентификации, не имеют ни-
чего общего с именами пользователей (регистрационными пользовательскими
302 Глава 4. Администрирование баз данных

именами) Windows или Unix. В Unix большая часть клиентов по умолчанию пы-
таются войти в систему, используя в качестве имени пользователя MySQL теку-
щее имя пользователя Unix, но делают они это только для удобства. Имена по
умолчанию можно легко изменить, потому что клиентские программы позволяют
задавать любое имя пользователя с помощью опции -и ИЛИ —user. Поскольку это
означает, что любой может попытаться подключиться к серверу, используя любое
имя пользователя, обеспечить безопасность для базы данных никак нельзя до тех
пор, пока все учетные записи не будут иметь пароли. Каждый, кто укажет имя
пользователя для учетной записи, не имеющей пароля, сможет успешно подсое-
диниться к серверу.
• В MySQL для имен пользователей разрешается использовать до 16 символов, а
вот в ОС максимальное количество допустимых символов может быть другим.
Например, имена пользователей Unix обычно ограничены 8 символами.
• Пароли MySQL не имеют ничего общего с паролями, используемыми для входа в
ОС. Не обязательно существует связь между паролем, который вводится для вхо-
да в Windows или Unix, и паролем, который необходим, чтобы получить доступ к
серверу MySQL в данной ОС.
• MySQL шифрует пароли с помощью своего собственного алгоритма. Такой тип
шифрования отличается от шифрования, используемого Unix во время входа в
систему. Шифрование паролей в MySQL эквивалентно шифрованию, осуществ-
ляемому с помощью SQL-функции PASSWORD (), а шифрование в Unix равнозначно
шифрованию с помощью SQL-функции ENCRYPT (). Начиная с версии 4.1, MySQL
использует более сложный метод аутентификации, который обеспечивает луч-
шую, чем в более ранних версиях, защиту паролей во время процесса подключе-
ния. Система остается безопасной, даже если перехвачены пакеты TCP/IP или са-
ма база данных mysql. (В более ранних версиях, хотя пароли и хранятся в таблице
user в зашифрованном виде, любой, кому удается узнать зашифрованный пароль,
может использовать его, чтобы подключиться к серверу MySQL.)
Во время установки MySQL в таблицы привилегий заносятся исходные учетные за-
писи. Эти записи получают имена и привилегии доступа, описанные в разделе 2.4.5, где
также обсуждается вопрос о назначении для них паролей. После этого, обычно, для ус-
тановки, изменения или удаления учетной записи MySQL используются операторы
GRANT И REVOKE.
При подключении к серверу через клиент MySQL необходимо указать имя пользова-
теля и пароль для учетной записи, которая будет использоваться:
shell> mysql —user=monty —password=guess имя_базы_данных
Если вы предпочитаете короткие варианты опций, команда будет выглядеть следую-
щим образом:
shell> mysql -u monty -pguess имя_базы_данных
Пробел между опцией -р и следующим за ней значением пароля не ставится. См.
раздел 4.4.4.
Предыдущие команды включают значение пароля в командной строке, что может
представлять определенный риск для безопасности системы (см. раздел 4.5.6). Чтобы
избежать этого, задавайте опцию —password или -р, не указывая после нее само значе-
ние пароля:
4.5. Управление учетными записями пользователей MySQL 303

shell> mysql —user=monty —password имя_базы_данных


shell> mysql -u monty -p имя__базы_данных
В таком случае программа клиента будет запрашивать ввод пароля. (В предложенных
выше примерах имя_базы_данных не интерпретируется как пароль, потому что между
имя_базы_данных и предшествующей ему опцией —password находится пробел.)
В некоторых системах вызов библиотеки, который MySQL использует для запроса
пароля, автоматически ограничивает пароль 8 символами. Причина этого заключается в
системной библиотеке, а не в MySQL. В MySQL какие-либо ограничения по длине паро-
ля отсутствуют. Чтобы обойти подобную проблему, сократите число символов в пароле
MySQL до восьми или меньше, или же поместите пароль в файл опций.

4.5.2. Добавление новых учетных записей в MySQL


Создавать учетные записи MySQL можно двумя способами:
• С помощью операторов GRANT.
• Путем внесения изменений непосредственно в таблицы привилегий MySQL.
Более предпочтительным методом считается использование операторов GRANT, по-
скольку они более компактны и менее подвержены ошибкам. Операторы GRANT доступ-
ны, начиная с MySQL 3.22.11; синтаксис операторов описан в книге "MySQL. Справоч-
ник по языку ".
Еще одна возможность для создания учетных записей предполагает использование
одной из нескольких доступных сторонних программ, которые предлагают функции по
администрированию учетных записей MySQL, такой, например, как программа
phpMyAdmin.
Приведенные ниже примеры иллюстрируют, как клиентская программа mysql ис-
пользуется для создания новых пользователей. Предполагается, что привилегии уста-
новлены со значениями по умолчанию, описанными в разделе 2.4.5. Это означает, что
для того чтобы внести какие-либо изменения, необходимо подключиться к серверу
MySQL от имени привилегированного (root) пользователя, учетная запись root при
этом должна иметь привилегию INSERT для базы данных mysql и административную
привилегию RELOAD.
Сначала воспользуйтесь программой mysql для подключения к серверу от имени
привилегированного (root) пользователя MySQL:
shell> mysql —user=root mysql
Если учетной записи root назначался пароль, в этой команде (и в других описывае-
мых ниже командах) также понадобится указать опцию —password или -р.
Подключившись к серверу от имени пользователя root, можно добавлять новые
учетные записи. Следующие операторы GRANT создают четыре новых учетных записи:
mysql> GRANT ALL PRIVILEGES ON *.* TO ' m o n t y ' @ ' l o c a l h o s t 1
-> IDENTIFIED BY ' s o m e j > a s s ' WITH GRANT OPTION;
mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty 1 @'%'
-> IDENTIFIED BY ' s o m e _ p a s s ' WITH GRANT OPTION;
mysql> GRANT RELOAD,PROCESS ON *.* TO ' a d m i n ' @ ' l o c a l h o s t ' ;
mysql> GRANT USAGE ON *.* TO ' d u m m y ' @ ' l o c a l h o s t ' ;
Учетные записи, созданные данными операторами GRANT, обладают следующими
свойствами:
304 Глава 4. Администрирование баз данных

• Две из представленных учетных записей с именем пользователя monty и паролем


some_pass являются учетными записями суперпользователя и имеют абсолютно
1
все привилегии. Первая ('monty'@'localhost ) может использоваться только при
подключениях с локального хоста. Вторая ('monty'@'%') - при подключениях с
любого другого хоста. Обратите внимание на необходимость в том, чтобы обе
учетные записи для monty могли подключаться к серверу с любого места от имени
monty. Без учетной записи localhost учетная запись анонимного пользователя для
localhost, создаваемая с помощью mysql_install_db, имела бы преимущество
при подсоединении monty с локального хоста. В результате monty рассматривался
бы как анонимный пользователь. Причина этого состоит в том, что учетная запись
анонимного пользователя имеет более точное значение в столбце Host, чем запись
•monty' @ ' % ' , и поэтому стоит первой в отсортированной таблице user. (Вопросы
по сортировке таблицы user рассматриваются в разделе 4.4.5.)
• Одна из учетных записей имеет имя пользователя admin и не имеет пароля. Она
может использоваться только при подключении с локального хоста. Ей предос-
тавлены административные привилегии RELOAD и PROCESS, которые позволяют
выполнять команды mysqladmin reload, mysqladmin r e f r e s h и mysqladmin
flush-xxx commands, а также mysqladmin p r o c e s s l i s t . Никаких привилегий для
доступа к любым базам данных у нее нет, но такие привилегии можно добавить
позже за счет выполнения дополнительных операторов GRANT.
• Оставшаяся учетная запись имеет имя пользователя dummy и не имеет пароля. Она
может использоваться только при подключениях с локального хоста. Привилегии
ей предоставлены не были. Привилегия USAGE в операторе GRANT присваивает всем
глобальным переменным значение ' N' и тем самым позволяет создавать учетную
запись без привилегий. Предполагается, что такой учетной записи позже будут
назначены отдельные привилегии.
В качестве альтернативы можно создать такие же учетные записи и напрямую, с по-
мощью операторов INSERT, после чего заставить сервер провести перезагрузку таблиц
привилегий:
shell> mysql --user=root mysql
mysql> INSERT INTO user
-> VALUES (' localhost', 'monty', PASSWORD (• somejaass •) ,
-> 'YVYVYVYVYVYVYVYVYVYVYVYVYVY');
mysql> INSERT INTO user
-> VALUES (' %' , 'monty' , PASSWORD (' some_pass') ,
-> 'YVYVY'/YVYVYVYVYVYVYVYVYVYVY');
mysql> INSERT INTO user SET Host='localhost',User='admin',
-> Reload_priv='Y', Process_priv='Y';
mysql> INSERT INTO user (Host,User,Password)
-> VALUES('localhost 1 ,'dummy', " ) ;
mysql> FLUSH PRIVILEGES;
Оператор FLUSH PRIVILEGES используется во время создания учетных записей с по-
мощью INSERT для того, чтобы сервер перезагрузил таблицы привилегий. В противном
случае изменения вступают в силу только после перезапуска сервера. При использова-
нии оператора GRANT необходимости в FLUSH PRIVILEGES нет.
4.5. Управление учетными записями пользователей MySQL 305

Функция PASSWORD () здесь используется для шифрования пароля. Оператор GRANT


сам шифрует пароль, поэтому функция PASSWORD () становится необязательной.
Значения ' Y' активизируют привилегии для учетных записей. В зависимости от вер-
сии MySQL, можно использовать разное количество значений ' Y' в первых двух опера-
торах INSERT. (Версии MySQL, предшествующие 3.22.11, включают меньшее число
столбцов привилегий; начиная с версии 4.0.2 их становится больше.) Для учетной записи
admin применяется более удобочитаемый расширенный синтаксис INSERT, включающий
и операторы SET, который доступен, начиная с версии MySQL 3.22.11.
В операторе INSERT для учетной записи dummy значения указаны только в столбцах
Host, User и Password таблицы user. Ни одна из привилегий не была задана явно, потому
абсолютно всем привилегиям MySQL присваивает значение по умолчанию ' N'. Это эк-
вивалентно тому, что делает оператор GRANT USAGE.
Обратите внимание, что для того, чтобы добавить учетную запись суперпользовате-
ля, создать запись со значениями ' Y' в столбцах привилегий необходимо только в таб-
лице user. Привилегии в таблице user являются глобальными, поэтому вставлять записи
в любых других таблицах привилегий не нужно.
В следующих примерах создаются три учетных записи, которым предоставляется
доступ к конкретным базам данных. Каждая из учетных записей имеет имя пользователя
custom и пароль obscure.
Чтобы создать учетные записи с помощью GRANT, используйте следующие команды:
s h e l l > mysql — u s e r = r o o t mysql
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
-> ON b a n k a c c o u n t . *
-> TO ' c u s t o m ' @ ' l o c a l h o s t '
-> IDENTIFIED BY ' o b s c u r e ' ;
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
-> ON e x p e n s e s . *
-> TO 'custom1@'whitehouse.gov'
-> IDENTIFIED BY 'obscure';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
-> ON customer.*
-> TO 'cus torn'@'server.domain'
-> IDENTIFIED BY 'obscure';
Эти учетные записи могут использоваться следующим образом:
• Первая учетная запись может получать доступ к базе данных bankaccount, но
только с локального хоста.
• Вторая учетная запись может получать доступ к базе данных expenses, но только
с хоста whitehouse. gov.
• Третья учетная запись может получать доступ к базе данных customer, но только
с хоста server .domain.
Для создания учетных записей custom без применения оператора GRANT, воспользуй-
тесь следующими командами INSERT, которые вносят изменения непосредственно в таб-
лицы привилегий:
shell> mysql —user=root mysql
mysql> INSERT INTO user (Host,User,Password)
-> VALUES('localhost','custom',PASSWORD('obscure'));
306 Глава 4. Администрирование баз данных

mysql> INSERT INTO user (Host,User,Password)


1
-> VALUES('whitehouse.gov','custom ,PASSWORD('obscure'));
mysql> INSERT INTO user (Host,User,Password)
-> VALUES('server.domain','custom',PASSWORD('obscure'));
mysql> INSERT INTO db
-> (Host,Db, User, Selectj?riv,Insert_jpriv,
-> Update_priv, Deletejpriv, Createjpriv, Dropjpriv)
-> VALUES('localhost','bankaccount','custom',
-> 'YVYVYVYVYVY');
mysql> INSERT INTO db
-> (Host,Db,User,Selectjpriv,Insert jpriv,
- > Updatejpriv, DeleteJ?riv, Create_priv, Drop jpriv)
-> VALUES('whitehouse.gov','expenses','custom',
-> 'Yf,'Y','Y','Y','Y','Y');
mysql> INSERT INTO db
-> (Hos t,Db,User,Select_priv,Insertjpriv,
-> Updatejpriv, Delete_priv, Create_priv, Drop_priv)
-> VALUES (' server.domain',' customer',' custom',
-> 'Y','Y','Y','Y','Y','Y');
mysql> FLUSH PRIVILEGES;
Первые три оператора INSERT добавляют записи в таблицу user, которые разрешают
пользователю custom подключаться с различных хостов с данным паролем, но не пре-
доставляют глобальных привилегий (всем глобальным привилегиям присвоено значение
по умолчанию 'N'). Следующие три оператора INSERT добавляют записи в таблицу db,
которые предоставляют привилегии для баз данных bankaccount, expenses и customer,
но только при доступе к ним с определенных хостов. И, как обычно, когда изменения
вносятся непосредственно в таблицы привилегий, должен быть выполнен оператор
FLUSH PRIVILEGES, обеспечивающий перезагрузку таблиц, после которой внесенные из-
менения вступают в силу.
Если конкретному пользователю необходимо предоставить доступ со всех машин в
данном домене (например, mydomain.com), можно использовать оператор GRANT, указав
групповой символ '%' в той части имени учетной записи, которая предназначена для
имени хоста:
mysql> GRANT ...
-> ON *.*
- > ТО ' myname' @ ' %. mydomain. com'
-> IDENTIFIED BY 'mypass1;
Чтобы сделать то же самое в случае, когда изменения вносятся непосредственно в
таблицы привилегий, поступите следующим образом:
mysql> INSERT INTO user (Host,User,Password,. . .)
-> VALUES (' %.mydomain. com','myname', PASSWORD ('mypass '),...);
mysql> FLUSH PRIVILEGES;

4.5.3. Удаление пользовательских учетных записей


из MySQL
Для удаления учетной записи служит оператор DROP USER, который был добавлен в
MySQL 4.1.1. В более старых версиях вместо него применяется оператор DELETE.
4.5. Управление учетными записями пользователей MySQL 307

Для удаления учетной записи пользователя MySQL потребуется выполнить следую-


щие шаги в указанном порядке:
1. С помощью оператора SHOW GRANTS определите, какие привилегии имеет учетная
запись.
2. С помощью оператора REVOKE отмените отображенные оператором SHOW GRANTS
привилегии. Это удалит записи для данного пользователя из всех таблиц привиле-
гий, за исключением таблицы user, и отменит все глобальные привилегии, пере-
численные в ней (в таблице user).
3. С помощью оператора DROP USER удалите учетную запись из таблицы user.
Оператор DROP USER появился в MySQL 4.1.1. В версиях, предшествующих 4.1.1,
сначала необходимо отменить привилегии учетной записи, как описано выше, и только
после этого удалить запись в таблице user и очистить таблицы привилегий:
mysql> DELETE FROM mysql.user
-> WHERE User='имя_пользователя* and Host='имя_хоста';
mysql> FLUSH PRIVILEGES;

4.5.4. Ограничение ресурсов учетной записи


До версии MySQL 4.0.2 единственным доступным методом ограничения использова-
ния ресурсов сервера MySQL была установка ненулевого значения системной перемен-
ной max_user_connections. Но этот метод является исключительно глобальным и не
разрешает управлять отдельными учетными записями. Кроме того, он ограничивает
только число одновременных соединений, устанавливаемых с помощью единственной
учетной записи, а не те операции, которые может выполнять уже подключившийся кли-
ент. Метод представляет интерес для большинства администраторов MySQL, особенно
для поставщиков услуг Internet.
Начиная с версии MySQL 4.0.2, появляется возможность ограничивать для опреде-
ленных учетных записей следующие серверные ресурсы:
• Количество разрешаемых для данной учетной записи запросов в час.
• Количество разрешаемых для данной учетной записи обновлений в час.
• Количество разрешаемых для данной учетной записи подключений к серверу в час.
Все выполняемые клиентом операторы засчитываются как запросы. Только операто-
ры, которые вносят изменения в базы данных и таблицы, учитываются как обновления.
Учетная запись в таком контексте - одна запись в таблице user. Каждая учетная за-
пись однозначно идентифицируется по своим значениям в столбцах User и Host.
Необходимым условием для применения такой функции является то, что таблица
user в базе данных mysql должна содержать столбцы, имеющие отношение к ресурсам.
Значения, ограничивающие использование ресурсов сервера, хранятся в столбцах
max_questions, max_updates и max_connections. Если эти столбцы отсутствуют, таблицу
user необходимо обновить; см. раздел 2.5.8.
Чтобы установить ограничения по ресурсам с помощью GRANT, воспользуйтесь кон-
струкцией WITH, указывая имя каждого ограничиваемого ресурса и максимальное число
раз, которое этот ресурс может использоваться в час. Например, для создания учетной
записи, имеющей доступ к базе данных customer, но ограниченный, выполните следую-
щие команды:
308 Глава 4. Администрирование баз данных

mysql> GRANT ALL ON c u s t o m e r . * TO ' f r a n c i s 1 @ ' l o c a l h o s t '


-> IDENTIFIED BY ' f r a n k '
-> WITH MAX_QUERIES_PER_HOUR 20
-> MAXJJPDATESJPERJtoUR 10
-> MAX_CONNECTIONS_PER_HOUR 5 ;

Типы ограничений не обязательно указываются с помощью WITH, но те, которые


именно так и заданы, могут следовать в любом порядке. Значение для каждого ограни-
чения должно представлять собой целое число, обозначающее количество запро-
сов/обновлений/соединений в час. Если в операторе GRANT не используется конструкция
WITH, значит, присвоено будет значение по умолчанию - 0 (то есть без ограничений).
Чтобы установить или изменить ограничения для существующей учетной записи, ис-
пользуйте оператор GRANT USAGE на глобальном уровне (ON *. *). Следующий оператор
изменяет для пользователя francis значение, ограничивающее число запросов, на 100:
mysql> GRANT USAGE ON * . * TO ' f r a n c i s ' @ ' l o c a l h o s t '
-> WITH MAX__QUERIES_PER_HOUR 1 0 0 ;

Данный оператор сохраняет все имеющиеся у данной учетной записи привилегии и


изменяет только указанные предельные значения.
Чтобы удалить существующее предельное значение, ему необходимо присвоить зна-
чение 0. Например, чтобы удалить ограничения по количеству допустимых для francis
соединений в час, выполните следующий оператор:
mysql> GRANT USAGE ON * . * TO ' f r a n c i s ' @ ' l o c a l h o s t '
-> WITH MAX_CONNECTIONSJ>ER_HOUR 0 ;

Подсчет количества используемых ресурсов происходит тогда, когда любое из пре-


дельных значений любой учетной записи не равно 0.
Во время работы сервер подсчитывает, сколько раз каждая учетная запись использует
тот или иной ресурс. Если пользователь в течение часа достигает установленного для
него предела по количеству соединений, то все его попытки подключиться до конца это-
го часа будут отклонены. То же самое происходит, и если пользователь исчерпал свой
лимит по числу запросов или обновлений: до конца часа эти ресурсы будут ему недос-
тупны. В каждом отдельном случае сервер будет выдавать соответствующее сообщение
об ошибке.
Подсчет ресурсов производится для каждой конкретной учетной записи, а не для ка-
ждого клиента. Например, если предельное значение по количеству запросов для дан-
ной учетной записи соответствует 50, увеличить его до 100, установив одновременно два
клиентских соединения с сервером, не получится. Запросы, обрабатываемые на обоих
соединениях, подсчитываются вместе.
Текущие предельные значения можно сбросить (присвоить им значение 0) как гло-
бально для всех учетных записей, так и индивидуально для каждого конкретного значения:
• Чтобы для всех учетных записей в столбцах ресурсов предельное значение снова
соответствовало 0, воспользуйтесь оператором FLUSH USER_RESOURCES или переза-
грузите таблицы привилегий (например, с помощью оператора FLUSH PRIVILEGES
или команды mysqladmin reload).
• Для конкретной учетной записи текущее предельное значение можно обнулить,
переназначив его. Для этого используется оператор GRANT USAGE, как описано
выше, и указывается предельное значение, равное значению, которое на данный
момент установлено для этой учетной записи.
4.5. Управление учетными записями пользователей MySQL 309

4.5.5. Назначение паролей для учетных записей


Пароли можно назначать в командной строке, используя команду mysqladmin:
shell> mysqladmin -u имя_пользователя -h имя_хоста password "новый_пароль"
Учетной записью, для которой данная команда сбрасывает пароль, является та, кото-
рая имеет в таблице user запись с подходящими значением имя_пользователя в столбце
User и значением имени хоста клиента, с которого вы подключаетесь, в столбце Host.
Еще один способ назначить пароль для учетной записи - воспользоваться операто-
ром SET PASSWORD:
m y s q l > SET PASSWORD FOR ' J e f f r e y ' @ ' % ' = PASSWORD('biscuit');
Только пользователи, подобные root, которые имеют права доступа для обновления
к базе данных mysql, могут изменять пароли других пользователей. Если вы подключи-
лись не как анонимный пользователь, то сможете изменить свой пароль, не указывая
конструкцию FOR:
mysql> SET PASSWORD = P A S S W O R D ( ' b i s c u i t ' ) ;

Воспользуйтесь оператором GRANT USAGE на глобальном уровне (ON *. *) для назна-


чения пароля учетной записи и при этом сохранения всех ее текущих привилегий:
m y s q l > GRANT USAGE ON * . * TO ' J e f f r e y ' @ ' % ' IDENTIFIED BY ' b i s c u i t ' ;
Хотя в целом предпочтительнее назначать пароли с помощью одного из описанных
выше методов, это также можно сделать и путем внесения изменений непосредственно в
таблицу user:
• Чтобы установить пароль во время создания новой учетной записи, укажите зна-
чение для столбца Password:
shell> mysql -u r o o t mysql
mysql> INSERT INTO u s e r (Host,User,Password)
-> VALUES('%','Jeffrey',PASSWORD('biscuit'));
mysql> FLUSH PRIVILEGES;
• Для изменения пароля уже существующей учетной записи используйте оператор
UPDATE, чтобы установить значение в столбце Password:
'shell> mysql -u root mysql
mysql> UPDATE user SET Password = PASSWORD('bagel')
-> WHERE Host = '%' AND User = ' f r a n c i s ' ;
mysql> FLUSH PRIVILEGES;
Когда пароль назначается с помощью операторов SET PASSWORD, INSERT или UPDATE,
обязательно нужно с помощью функции PASSWORD () зашифровать его. (Единственный
случай, когда функция PASSWORD () не применяется, это если пароль имеет пустое значе-
ние.) Эта функция обязательна, потому что пароли хранятся в таблице user в зашифро-
ванном виде, а не виде открытого текста. Если забыть об этом и установить пароль сле-
дующим образом:
s h e l l > mysql -u root mysql
mysql> INSERT INTO user (Host,User,Password)
-> VALUES('%','Jeffrey','biscuit');
mysql> FLUSH PRIVILEGES;
310 Глава 4. Администрирование баз данных

то в таблице user в качестве пароля будет сохранено символьное, а не зашифрованное


значение ' b i s c u i t ' . При попытке пользователя Jeffrey подключиться к серверу с по-
мощью этого пароля, значение пароля шифруется и сравнивается с тем, которое хранит-
ся в таблице user. Однако поскольку в таблице находится символьное значение
' biscuit', совпадение обнаружено не будет и сервер отклонит запрос на соединение:
shell> mysql -u Jeffrey -pbiscuit test
Access denied
В доступе отказано
Если пароль устанавливается с помощью оператора GRANT.. .IDENTIFIED BY или ко-
манды mysqladmin password, шифрование (в обоих случаях) выполняется автоматиче-
ски, и использовать функцию PASSWORD () не нужно.
На заметку!
Шифрование паролей с помощью функции PASSWORD!) отличается от шифрования в Unix. См.
\ раздел 4.5.1.

4.5.6. Как обезопасить свой пароль


На административном уровне никогда нельзя предоставлять доступ к таблице
mysql.user обычным пользователям. Пароли в таблице user хранятся в зашифрованном
виде, но в версиях MySQL, предшествующих 4.1, знание зашифрованного пароля опре-
деленной учетной записи делает возможным подключение к серверу через эту запись.
При запуске клиентской программы для подключения к серверу MySQL не рекомен-
дуется указывать свой пароль таким образом, чтобы его могли увидеть другие пользова-
тели. Возможные методы задания пароля в таком случае, а также степени риска при ис-
пользовании каждого из них представлены ниже.
• Использование опции -рпароль или —pass wo r б^пароль в командной строке, на-
пример:
shell> mysql -u francis -pfrank имя_базы_данных
Это удобно, но небезопасно, поскольку ваш пароль становится видимым для про-
грамм вывода состояния системы, таких как ps, которые могут быть вызваны дру-
гими пользователями в целях просмотра командных строк. Во время инициализа-
ции клиенты MySQL обычно перезаписывают аргументы пароля в командной
строке с помощью нулей, но по-прежнему остается короткий промежуток време-
ни, в течение которого значение пароля остается видимым.
• Использование опции -р или —password без указания пароля. В этом случае про-
грамма клиента запрашивает пароль из терминала:
shell> mysql -u francis -p имя_базы_данных
Enter password: ********
Символы '*' указывают, где вводится пароль. Пароль во время ввода не отобра-
жается.
Намного безопаснее вводить пароль таким образом, нежели задавать его в ко-
мандной строке, поскольку в этом случае он невидим для других пользователей.
Однако этот метод подходит только для программ, работающих в интерактивном
режиме. При вызове клиента из неинтерактивного сценария ввести пароль с тер-
4.5. Управление учетными записями пользователей MySQL 311

минала не получится. В некоторых системах первая строка вашего сценария счи-


тывается и интерпретируется как ваш пароль (что совершенно неправильно).
• Хранение пароля в файле опций. Например, в Unix его можно разместить в разде-
ле [client] файла .my.cnf в домашнем каталоге:
[client]
pas s wo r (1=пароль
Если пароль хранится в файле .my.cnf, нельзя, чтобы он был доступен кому-
нибудь, кроме вас. Чтобы гарантировать это, в качестве режима доступа к файлу
установите значение 400 или 600:
shell> chmod 600 .my.cnf
Более подробную информацию, касающуюся файлов опций, можно найти в раз-
деле 3.3.2.
• Хранение пароля в переменной окружения MYSQL_PWD. Такой метод является
крайне небезопасным, потому применяться не должен. Некоторые версии про-
граммы ps включают опцию для отображения переменных окружения текущих
процессов. То есть, если установить MYSQLPWD, ваш пароль будет виден всем
пользователям, работающим с ps. Даже в системах, не использующих такую вер-
сию ps, предполагать, что других способов, с помощью которых пользователи мо-
гут проверить переменные окружения, не существует, крайне неразумно. См.
приложение Б.
В конечном итоге наиболее безопасными методами являются настройка клиентской
программы для запроса на ввод пароля и указание пароля в защищенном надлежащим
образом файле опций.

4.5.7. Использование безопасных соединений


Начиная с версии 4.0.0, MySQL поддерживает безопасные (шифрованные) соедине-
ния между клиентами MySQL и сервером с помощью протокола защищенных сокетов
(Secure Sockets Layer - SSL). В настоящем разделе описано использование SSL-
соединений, а также установка SSH в среде Windows.
Предполагается, что стандартная конфигурация MySQL должна быть максимально
быстрой, поэтому шифрованные соединения по умолчанию не используются. В против-
ном случае это бы замедляло передачу данных через клиент-серверный протокол. Шиф-
рование данных приводит к дополнительной нагрузке на процессор и может задержи-
вать выполнение других задач MySQL. Для приложений, безопасность которых должна
обеспечиваться посредством шифрованных соединений, обязательно потребуются доба-
вочные вычислительные операции.
MySQL позволяет активизировать функцию шифрования данных для каждого соеди-
нения в отдельности. Предлагается возможность выбирать, в соответствии с требова-
ниями того или иного приложения, что конкретно использовать: нешифрованное соеди-
нение или безопасное шифрованное SSL-соединение.

4.5.7.1. Основные сведения о SSL


Чтобы понять, как MySQL использует SSL, прежде всего следует разобраться с ос-
новными понятиями SSL и Х509. Те, кто уже знаком с ними, могут пропустить этот
раздел.
312 Глава 4. Администрирование баз данных

По умолчанию MySQL использует нешифрованные соединения между клиентом и


сервером. Это значит, что любой, у кого есть доступ к сети, может просматривать весь
ваш трафик, а также посылаемые/получаемые данные, и даже изменять их во время са-
мой передачи. Чтобы хоть немного улучшить степень защиты, можно при вызове кли-
ентских программ сжимать пересылаемые между клиентом и сервером данные с помо-
щью опции -compress. Однако настойчивого хакера это никак не остановит.
Если необходима безопасная передача информации через сеть, нешифрованное со-
единение в таком случае точно не подходит. Шифрование - это способ сделать любую
информацию недоступной для прочтения. Фактически, на сегодняшний день алгоритмы
шифрования требуют новых дополнительных элементов безопасности, чтобы суметь
противостоять большей части уже известных типов атак, таких как изменение порядка
зашифрованных сообщений или воспроизведение данных дважды.
Протокол защищенных сокетов SSL - это протокол, который использует различные
алгоритмы шифрования для гарантии, что получаемым через общедоступную сеть дан-
ным можно доверять. Он с помощью своих механизмов фиксирует любые вносимые в
передаваемую информацию изменения, а также потерю или повтор данных. SSL также
задействует алгоритмы, обеспечивающие верификацию с помощью стандарта Х509.
Стандарт Х509 позволяет проводить идентификацию личности в Internet. Чаще всего
он используется в приложениях электронной коммерции. Если кратко, то должна суще-
ствовать некая компания под названием "Certificate Authority" ("Центр сертификации"),
которая назначает электронные сертификаты любому, кому они нужны. Сертификаты
основаны на ассиметричных алгоритмах шифрования, включающих два ключа (откры-
тый и секретный). Владелец сертификата может предъявить его другой стороне в каче-
стве подтверждения своей личности. Сертификат содержит открытый ключ владельца.
Любые данные, зашифрованные с помощью этого открытого ключа, могут быть рас-
шифрованы только при наличии соответствующего секретного ключа, который хранится
у владельца сертификата.
Для получения более подробной информации по SSL, X509 или шифрованию восполь-
зуйтесь излюбленной поисковой машиной в Internet, набрав интересующие вас слова.

4.5.7.2. Требования
Для использования соединений между сервером MySQL и программами клиентов,
необходимо, чтобы система поддерживала OpenSSL, а версия MySQL была не ниже.
4.0.0.
Чтобы безопасные соединения начали работать с MySQL, понадобится выполнить
следующие действия:
1. Установите библиотеку OpenSSL. MySQL была протестирована с OpenSSL O.9.6.
Найти OpenSSL можно по адресу http: //www.openessl .org.
2. Во время конфигурирования MySQL запустите сценарий configure с опциями
—with-vio и —with-openessl.
3. Убедитесь, что таблицы привилегий обновлялись и теперь содержат столбцы для
SSL в таблице mysql.user. Это необходимо, если используется версия MySQL,
предшествующая 4.0.0. Процедура обновления описана в разделе 2.5.8.
4. Узнать, поддерживает ли сервер mysqld протокол OpenSSL, можно, проверив зна-
чение системной переменной have_openessl:
4.5. Управление учетными записями пользователей M y S Q L 313

mysql> SHOW VARIABLES LIKE 'have_openssl';


+ + +
| Variable_name | Value I
+ + +

| have_openssl | YES |

Если значением является YES, значит, сервер поддерживает соединения OpenSSL.

4.5.7.3. Настройка SSL-сертификатов для MySQL


Ниже представлен пример настройки SSL-сертификатов для MySQL:
DIR=NpwdVopenssl
PRIV=$DIR/private
rakdir $DIR $PRIV $DIR/newcerts
cp /usr/share/ssl/openssl.cnf $DIR
replace ./demoCA $DIR -- $DIR/openssl.cnf
# Создание необходимых файлов: $database, $serial и
# каталог $new_certs_dir (необязательно)
touch $DIR/index.txt
echo "01" > $DIR/serial
#
# Создание Certificate Authority (CA)(Центра сертификации)
#
openssl req -new -x509 -keyout $PRIV/cakey.pem -out $DIR/cacert.pem\
-config $DIR/openssl.cnf
# Образец выходных данных:
# Используется конфигурация из /horae/monty/openssl/openssl.cnf
# Генерация секретного ключа длиной 1024 бит с помощью
# шифрования RSA
# ++++++
# ++++++
# Запись нового секретного ключа в
# '/home/monty/openssl/private/cakey.pem1
# Ввод парольной фразы в формате РЕМ:
# Верификация пароля - Введите парольную фразу в формате РЕМ:
#
# После этого последует запрос на ввод информации, которая будет
# включена в сертификат.
# Такая информация называется "отличительным именем", или DN
# (Distinguished Name).
# Строк для ввода всего несколько и некоторые из них можно
# оставить пустыми.
# Некоторым из них будет присвоено значение по умолчанию.
# При вводе '.' строка будет оставлена незаполненной.
#
# Страна (код из двух букв) [AU]:FI
# Штат или область (полностью) [какой-нибудь штат]:.
# Местонахождение (например, город) []:
# Название организации (например, компания) [Internet Widgits Pty Ltd]:MySQL AB
314 Глава 4. Администрирование баз данных

# Отдел [ ]:
# Имя (например, ВАШЕ имя) []:администратор MySQL
# Адрес электронной почты []:
#
# Создание запроса к серверу и ключа
#
openssl req -new -keyout $DIR/server-key.pem -out \
$DIR/server-req.pem -days 3600 -config $DIR/openssl.cnf
# Образец выходных данных:
# Используется конфигурация из /home/monty/openssl/openssl.cnf
# Генерация секретного ключа размером 1024 бит с помощью
# шифрования RSA
# ++++++
# ++++++
# Запись нового секретного ключа в
# '/home/monty/openssl/private/cakey.pem'
# Ввод парольной фразы в формате РЕМ:
# Верификация пароля - Введите парольную фразу в формате РЕМ:
#
# После этого последует запрос на ввод информации, которая будет
# включена в сертификат.
# Такая информация называется "отличительным именем", или DN
# (Distinguished Name).
# Строк для ввода всего несколько и некоторые из них
# можно оставить пустыми.
# Некоторым из них будет присвоено значение по умолчанию.
# При вводе '.' строка будет оставлена незаполненной.
#
# Страна (код из двух букв) [AU]:FI
# Штат или область (полностью) [какой-нибудь штат]:.
# Местонахождение (например, город) []:
# Название организации (например, компания) [Internet Widgits Pty Ltd]:MySQL AB
# Отдел []:
# Имя (например, ВАШЕ имя) []:администратор MySQL
# Адрес электронной почты []:
#
# Пожалуйста, введите следующие 'дополнительные' атрибуты,
# отсылаемые вместе с сертификатом
# Пароль вызова[]:
# Название компании (необязательно)[]:
#
# Удаление парольной фразы из ключа (необязательно)
#
openssl rsa -in $DIR/server-key.pem -out $DIR/server-key.pem
#
# Подписание сертификата сервера
#
openssl ca -policy policy_anything -out $DIR/server-cert.pem \
-config $DIR/openssl.cnf -infiles $DIR/server-req.pem
4.5. Управление учетными записями пользователей MySQL 315

# Образец выходных данных:


# Используется конфигурация из /home/monty/openssl/openssl.cnf
# Введите парольную фразу в формате РЕМ:
# Проверьте, чтобы подпись в запросе совпадала.
# Подпись совпала
# Отличительное имя будет выглядеть следующим образом:
# Страна :ВЫВОД:'FI'
1
# Организация :ВЫВОД:'MySQL AB
# Имя :ВЫВОД:'MySQL admin'
# Сертификат действителен до 13 сентября 14:22:46 2005 (по
# Гринвичу) (в течение 365 дней)
# Подписать сертификат? [да(у)/нет(п)]:у (да)
#
#
# Создано 1 из 1 сертификатов, продолжить? [да(у)/нет(п)]:у (да)
# Внесение новой записи в базу данных
# База данных обновлена
#
# Создание запроса к клиенту и ключа
#
openssl req -new -keyout $DIR/client-key.pem -out \
$DIR/client-req.pem -days 3600 -config $DIR/openssl.cnf
# Образец выходных данных:
# Используется конфигурация из /home/monty/openssl/openssl.cnf
# Генерация секретного ключа размером 1024 бит с помощью
# шифрования RSA
# ++++++
# ++++++
# Запись нового секретного ключа в
# '/home/monty/openssl/client-key.pem'
# Ввод парольной фразы в формате РЕМ:
# Верификация пароля - Введите парольную фразу в формате РЕМ:
#
# После этого последует запрос на ввод информации, которая будет
# включена в сертификат.
# Такая информация называется "отличительным именем", или DN
# (Distinguished Name).
# Строк для ввода всего несколько и некоторые из них
# можно оставить пустыми.
# Некоторым из них будет присвоено значение по умолчанию.
# При вводе '.' строка будет оставлена незаполненной.
#
# Страна (код из двух букв) [AU]:FI
# Штат или область (полностью) [какой-нибудь штат]:.
# Местонахождение (например, город ) []:
# Название организации (например, компания) [Internet Widgits Pty
# Ltd]:MySQL AB
# Отдел []:
# Имя (например, ВАШЕ имя) []:администратор MySQL
# Электронный адрес [ ]:
316 Глава 4. Администрирование баз данных

# •

# Пожалуйста, введите следующие 'дополнительные' атрибуты,


# отсылаемые вместе с сертификатом
# Пароль вызова[]:
# Название компании (необязательно)[]:
#
# Удаление парольной фразы из ключа (необязательно)
#
openssl rsa -in $DIR/client-key.pem -out $DIR/client-key.pem
#
# Подписание сертификата клиента
#
openssl ca -policy policy_anything -out $DIR/client-cert.pem \
-config $DIR/openssl.cnf -infiles $DIR/client-req.pem
# Образец выходных данных:
# Используется конфигурация из /home/monty/openssl/openssl.cnf
# Введите парольную фразу в формате РЕМ:
# Проверьте, чтобы подпись в запросе совпадала.
# Подпись совпала
# Отличительное имя будет выглядеть следующим образом:
# Страна :ВЫВОД:•FI'
# Организация :ВЫВОД:'MySQL AB'
# Имя :ВЫВОД:'MySQL admin'
# Сертификат действителен до 13 сентября 14:22:46 2005 (по
# Гринвичу) (в течение 365 дней)
# Подписать сертификат? [да(у)/нет(п)]:у (да)
#
#
# Создано 1 из 1 сертификатов, продолжить? [да(у)/нет(п)]:у (да)
# Внесение новой записи в базу данных
# База данных обновлена
#
# Создание файла my.cnf, который можно использовать для
# тестирования сертификатов
#
cnf=""
cnf="$cnf [client]"
cnf="$cnf ssl-ca=$DIR/cacert.pem"
cnf="$cnf ssl-cert=$DIR/client-cert.pem"
cnf="$cnf ssl-key=$DIR/client-key.pem"
cnf="$cnf [mysqld]"
cnf="$cnf ssl-ca=$DIR/cacert.pem"
cnf="$cnf ssl-cert=$DIR/server-cert.pem"
cnf="$cnf ssl-key=$DIR/server-key.pem"
echo $cnf | replace " " '
' > $DIR/my.cnf
Чтобы протестировать SSL-соединения, запустите сервер следующим образом:
shell> mysqld --defaults-file=$DIR/my.cnf &
где $DIR - это путь к каталогу, в котором находится образец файла опций my. cnf.
4.5. Управление учетными записями пользователей MySQL 317

Затем вызовите программу клиента с использованием того же самого файла опций:


shell> mysql --defaults-file=$DIR/my.cnf
При наличии исходного дистрибутива MySQL, протестировать созданные сертифи-
каты можно, изменив упомянутый выше файл my.cnf так, чтобы он ссылался на демон-
страционные сертификаты и файлы ключей в каталоге SSL.

4.5.7.4. SSL-опции GRANT


Кроме обычной аутентификации с помощью пароля и имени пользователя, MySQL
может дополнительно проверять и атрибуты сертификатов Х509. Чтобы задать относя-
щиеся к SSL опции для учетной записи MySQL, используйте конструкцию REQUIRE в
операторе GRANT, как описано в книге "MySQL. Справочник по языку".

4.5.7.5. Опции командной строки SSL


Ниже представлен список опций, с помощью которых задается использование SSL,
файлов сертификатов и файлов ключей. Эти опции доступны, начиная с MySQL 4.O. Их
можно задавать как в командной строке, так и в файле опций.
• —ssl. Для сервера данная опция указывает, что сервер разрешает использование
SSL-соединений. Для программы клиента эта опция разрешает клиенту подклю-
чаться к серверу через SSL. Чтобы начать использовать SSL-соединение, одной
этой опции не достаточно, необходимо также задать опции —sslca, —ssl-cert и
—ssl-key.
Опция —ssl чаще применяется в своей противоположной форме —skip-ssl или
—SS1=0,TO есть, чтобы указать, что протокол SSL использоваться не должен.
Обратите внимание, что --ssl не требует SSL-соединения. Например, если сер-
вер или клиент скомпилированы без поддержки SSL, использоваться будет обыч-
ное нешифрованное соединение.
Самый безопасный способ гарантировать использование SSL-соединения - это
создать на сервере учетную запись, включающую конструкцию REQUIRE SSL в
операторе GRANT, и затем применять ее для подключения к серверу, предваритель-
но позаботившись о том, чтобы и для сервера и для клиента была активизирована
поддержка SSL.
• —ssi-са=имя_файла. Путь к файлу со списком доверяемых центров сертификации
(СА) SSL.
• —ssi-capatЬ=имя_каталога. Путь к каталогу, в котором содержаться сертифика-
ты доверяемых СА SSL в формате РЕМ (формат электронной почты повышенной
секретности).
• —s si-сет1=ммя_файла. Имя файла сертификата SSL, который должен использо-
ваться для установки безопасного соединения.
• —ssl-С1р\\ег=список_шифров. Список допустимых шифров, которые будут ис-
пользоваться для SSL-шифрования. список_шфров имеет тот же формат, что и
команда openssl ciphers.
Пример: --ssl-cipher=ALL:-AES:-EXP
• —ssl-keу=имя_файла. Имя файла ключей SSL, который должен использоваться
для установки безопасного соединения.
318 Глава 4. Администрирование баз данных

4.5.7.6. Удаленное соединение с MySQL с использованием SSH в


Windows
В этом разделе представлены примечания о том, как установить безопасное соедине-
ние с удаленным сервером MySQL при помощи SSH, составленные Дэвидом Карлсоном
(David Carlson, [email protected]).
1. Установите SSH-клиент в своей системе Windows. Из всех, что удалось найти,
лучший клиент (с точки зрения пользователей) - это клиент, предлагаемый
SecureCRT (http://www.vandyke.com/). Еще один неплохой вариантом является
f-secure (http://www.f-secure.com/). Кроме того, на Google по адресу
http://directory.google.com/Top/Computers/Security/Products_and_Tools/Cry
ptography/SSH/Clients/Windows/ можно найти и другие бесплатные версии.
2. Запустите Windows-клиент SSH. Установите Host_Name = ит-адрес_или_1Р-
aMpec_cepBepa_MySQL, после чего установите user±6.=ваш_идентификатор_пользователя
для входа в систему. Значение userid может отличаться от имени пользователя
учетной записи MySQL.
3. Задайте переадресацию портов: либо удаленного типа (local_port: 330б,
remote_host: иЯ1-адрес_или_1Р-адрес_сервера__Му50Ь, remote_port: 3306), либо
локального типа (port: 3306, host: localhost, remote port: 3306).
4. Сохраните все изменения; в противном случае, в следующий раз все придется ус-
танавливать заново.
5. Подключитесь к серверу с помощью только что созданного сеанса SSH.
6. В Windows запустите какое-нибудь ODBC-приложение (например, Access).
7. Создайте новый файл в Windows и ссылку на MySQL с помощью ODBC-драйвера
так, как это обычно делается, только вместо имя_сервера_Му8()1 для серверного
хоста MySQL введите localhost.
После этого у вас должно появиться ODBC-соединение с MySQL, шифруемое с ис-
пользованием SSH.

46. Предотвращение аварий и восстановление


системы
В настоящем разделе рассматриваются вопросы, касающиеся резервного копирова-
ния баз данных и обслуживания таблиц. Синтаксис описываемых здесь SQL-операторов
можно найти в книге MySQL. Справочник по языку. Большая часть информации этого
раздела в первую очередь касается таблиц My ISAM. Процедуры резервного копирования
баз данных InnoDB приводятся в разделе 9.9.

4.6.1. Резервное копирование баз данных


Поскольку таблицы MySQL хранятся в виде файлов, их резервное копирование вы-
полняется достаточно просто. Чтобы добиться согласованности резервных копий, снача-
ла для соответствующих таблиц выполните LOCK TABLES, а затем для них же - FLUSH
TABLES. Необходима только блокировка по чтению, поскольку это позволит другим кли-
ентам продолжать запрашивать таблицы в то время, как будет создаваться копия файлов
4.6. Предотвращение аварий и восстановление системы 319

каталога базы данных. Оператор FLUSH TABLES нужен, чтобы гарантировать, что все ак-
тивные страницы индексов будут записаны на диск до начала резервного копирования.
Если требуется выполнить резервное копирование таблицы на уровне SQL, сущест-
вует возможность воспользоваться операторами SELECT INTO.. .OUTFILE или BACKUP
TABLE. Для SELECT INTO.. .OUTFILE выходной файл существовать не может; то же самое
касается и BACKUP TABLE в версиях MySQL 3.23.56 и MySQL 4.0.12, поскольку это бы
представляло угрозу для безопасности системы.
Еще один способ провести резервное копирование базы данных - это использовать
программу mysqldump или сценарий mysqlhotcopy. См. разделы 7.8 и 7.9.
1. Выполните полное резервное копирование базы данных:
shell> mysqldump —tab=/путь/к/'определенному/каталогу
—opt имя_базы_данных
или
shell> mysqlhotcopy имя_базы_данных /путь/к/определенному/каталогу
Можно также просто скопировать все файлы таблиц (*.frm, *.MYD и *.MYI), пока
сервер не осуществляет никаких обновлений. Сценарий mysqlhotcopy использует
именно такой метод. Однако обратите внимание, что если база данных содержит
таблицы innoDB, этот метод работать не будет. InnoDB не хранит файлы таблиц в
каталогах баз данных, и поэтому mysqlhotcopy подходит только для таблиц
My IS AM и ISAM.
2. Остановите mysqld, если он работает, и перезапустите его с опцией - - l o g - b i n [ =
имя_файла]. См. раздел 4.8.4. В файлах бинарного журнала данные, необходимые
для репликации, содержатся в такой же последовательности, в которой вносились
изменения в базу данных, начиная с момента, когда была запущена программа
mysqldump.
Если сервер MySQL является подчиненным сервером репликации, тогда, независимо
от выбранного метода резервного копирования, во время его проведения на таком серве-
ре обязательно следует создавать также резервную копию файлов m a s t e r . i n f o и r e l a y -
log, info. Эти файлы всегда нужны для возобновления репликации после восстановле-
ния данных подчиненного сервера. Если во время репликации на подчиненном сервере
используются команды LOAD DATA INFILE, потребуется сделать копии всех файлов
SQL_LOAD-*, которые могут находиться в каталоге, указанном в опции - - s l a v e - l o a d -
tmpdir. (Если имя этого каталога не задано, по умолчанию ему будет присвоено значе-
ние переменной tmpdir). Подчиненному серверу понадобятся эти файлы, чтобы возоб-
новить репликацию любых прерванных операций LOAD DATA INFILE.
Если приходится восстанавливать таблицы My ISAM, попробуйте сначала сделать это с
помощью REPAIR TABLE или myisamchk -г. В 99,9% случаев это должно сработать. Если
myisamchk не помогает, попытайтесь выполнить следующее. (Обратите внимание, что
это принесет результаты только в том случае, если была активизирована функция реги-
стрирования данных в бинарном журнале путем запуска сервера с опцией — l o g - b i n ; см.
раздел 4.8.4.)
1. Восстановите исходную резервную копию, полученную с помощью mysqldump,
или бинарную копию.
320 Глава 4. Администрирование баз данных

2. Выполните следующую команду, чтобы запустить повторное обновление записей


бинарного журнала:
shell> mysqlbinlog имя_хоста-Ып. [0-9]* | mysql
В отдельном случае может понадобиться запустить повторное обновление только
определенных бинарных журналов (обычно выполняется повторное обновление
всех записей, за исключением лишь некоторых некорректных запросов, занесен-
ных в бинарные журналы, начиная с даты проведения резервного копирования
после восстановления). За более подробной информацией, касающейся утилиты
mysqlbinlog и ее применения, обращайтесь в раздел 7.5.
Если используются журналы обновлений, обработать их содержимое можно сле-
дующим образом:
shell> I s - I - t -г имя_хоста.[0-9]* | xargs cat | mysql
Is используется, чтобы рассортировать файлы журнала обновлений в правильном
порядке.
Также можно осуществлять избирательное резервное копирование отдельных файлов:
• Чтобы построить дамп таблицы, используйте SELECT * INTO OUTFILE химя_файла*
FROM 'имя_ та блицы'.
• Чтобы перезагрузить таблицу, используйте для восстановления LOAD DATA INFILE
' имя_файла' REPLACE... Во избежание появления дубликатов записей, у таблицы
должен быть индекс UNIQUE или PRIMARY KEY. Применение ключевого слова
REPLACE приводит к замене старых записей новыми, когда новая запись дублирует
старую по значению уникального ключа.
В случае проблем с производительностью сервера во время резервного копирования
помочь может установка репликации и проведение копирования не на главном, а на под-
чиненном сервере. См. раздел 5.1.
Если используется файловая система Veritas, резервное копирование можно осущест-
влять следующим образом:
1. Из программы клиента выполните FLUSH TABLES WITH READ LOCK.
2. Из другой командной оболочки выполните mount vxf s snapshot.
3. Из первого клиента выполните UNLOCK TABLES.
4. Скопируйте файлы из снимка.
5. Размонтируйте снимок.

4.6.2. Обслуживание и восстановление


таблиц после аварий
Ниже дается описание применения myisamchk для проверки или восстановления таб-
лиц My ISAM (таблиц, хранящихся в файлах .MYI и .MYD). Те же самые концепции приме-
нимы и в отношении isamchk при проверках и восстановлении таблиц ISAM (таблиц, хра-
нящихся в файлах . ISM и . ISD). См. главу 8.
Утилиту myisamchk можно использовать для получения информации о таблицах базы
данных или же для проверки необходимости исправления или оптимизации таблиц. В
следующих разделах описывается, как вызвать myisamchk (включая описание доступных
4.6. Предотвращение аварий и восстановление системы 321

в ней опций), как настроить график обслуживания таблиц и как с помощью myisamchk
выполнять различные функции.
Хотя восстановление таблиц с помощью myisamchk - процесс достаточно безопас-
ный, прежде чем приступать к нему (или любой другой операции по обслуживанию,
подразумевающей внесение многочисленных изменений в таблицу), лучше все-таки
сделать резервную копию.
Выполняемые myisamchk операции, в которых задействуются индексы, могут привес-
ти к построению индексов FULLTEXT с такими полнотекстовыми параметрами, что они
станут несовместимыми со значениями, используемыми сервером MySQL. Чтобы избе-
жать этого, следуйте инструкциям из раздела 4.6.2.2.
В большинстве случаев может оказаться намного проще для обслуживания таблиц
My ISAM использовать SQL-операторы, которые выполняют те же операции, что и
myisamchk:
• Для проверки и восстановления таблиц MylSAM используйте CHECK TABLE или
REPAIR TABLE.
• Для оптимизации таблиц MylSAM используйте OPTIMIZE TABLE.
• Для анализа таблиц MylSAM используйте ANALYZE TABLE.
Эти операторы вводились в различных версиях, но все они доступны, начиная с вер-
сии MySQL 3.23.14. Их можно использовать напрямую или посредством клиентской
программы mysqlcheck, обеспечивающей для них интерфейс командной стоки.
Одно из преимуществ данных операторов по сравнению с myisamchk заключается в
том, что при их использовании всю работу делает сервер. В случае, когда применяется
утилита myisamchk, необходимо проверять, чтобы таблицы в это же время не использо-
вались сервером. В противном случае не исключено нежелательное взаимодействие ме-
жду myisamchk и сервером.

4.6.2.1. Синтаксис запуска myisamchk


Запускайте myisamchk следующим образом:
s h e l l > myisamchk [опции] имя^таблицы
В опциях указывается, что myisamchk должна делать. Сами опции описываются в сле-
дующих разделах. Также список опций можно просмотреть с помощью myisamchk —help.
Если опции не заданы, myisamchk по умолчанию просто проверяет таблицу. Чтобы
получить более подробную информацию или заставить myisamchk выполнить опреде-
ленные корректирующие действия, необходимо задавать опции так, как описывается
ниже.
имя_таблицы - это таблица базы данных, которую следует проверить или восстано-
вить. Если myisamchk запускается не из каталога базы данных, необходимо указать к не-
му путь, поскольку myisamchk не знает, где расположена база данных. На самом деле для
myisamchk не имеет значения, размещены рабочие файлы в каталоге базы данных или
нет. Файлы, соответствующие таблице базы данных, можно скопировать в другой ката-
лог и провести в нем операции по их восстановлению.
При желании можно задать имена нескольких таблиц в командной строке myisamchk.
Также существует возможность указать таблицу через имя индексного файла (файл с
суффиксом .MYI). Это позволяет задавать все таблицы из каталога с помощью шаблона
322 Глава 4. Администрирование баз данных

* .MYI. Например, находясь в каталоге базы данных, все таблицы My ISAM в этом каталоге
можно проверить следующим образом:
shell> myisamchk *.MYI
Проверить все таблицы в каталоге базы данных, не находясь в нем, можно, указав
путь к этому каталогу:
shell> myisamchk /путь/к/каталогу_базы_данных/* .MYI
Также, возможно даже проверить все таблицы во всех базах данных, указав группо-
вой символ ('*') и путь к каталогу данных MySQL:
shell> myisamchk /путь/к/каталогу ^данных/*I* .MYI
Для быстрой проверки всех таблиц My ISAM и ISAM рекомендуется следующий способ:
shell> myisamchk —silent —fast /путь/к/каталогу данных/* /* .MYI
shell> isamchk —silent /путь/к/каталогу_данных/*/*.ISM
Если необходимо проверить все таблицы My ISAM и ISAM и восстановить поврежден-
ные, можно воспользоваться следующими командами:
shell> myisamchk —silent —force —fast —update-state \
-0 keyjbuffer=64M -0 sort_buffer=64M \
-0 read_buffer=lM -0 writeJmffer=lM \
/путь/к/каталогу_данных/*/*.MYI
shell> isamchk —silent —force -0 keyJbuffer=64M \
-0 sortjDuffer=64M -0 read_buffer=lM -0 write_buffer=lM \
/путь/к/каталогу__данных/*/*. ISM
Эти команды предполагают наличие более чем 64 Мбайт свободного пространства на
диске. Детальнее вопрос о распределении памяти с помощью myisamchk рассматривается
в разделе 4.6.2.6.
Необходимо убедиться, что во время запуска утилиты myisamchk таблицы больше
никакой другой программой не используются. В противном случае myisamchk при запус-
ке может выдать следующее сообщение об ошибке:
warning: clients are using or haven't closed the table properly
предупреждение: клиенты используют или не закрыли должным образом таблицу
Это указывает на попытку проверить таблицу, которая обновлялась другой програм-
мой (такой как, например, сервер mysqld), пока не закрывшей файл или завершившей
свою работу, не успев корректно закрыть файл.
Если mysqld выполняется, необходимо обязательно, с помощью FLUSH TABLES, заста-
вить его очистить все находящиеся в буфере памяти изменения таблиц. После этого по-
требуется обеспечить, чтобы никто не использовал таблицы до тех пор, пока функцио-
нирует myisamchk. Самый простой способ избежать этой проблемы - для проверки таб-
лиц вместо утилиты myisamchk использовать оператор CHECK TABLE.

4.6.2.2. Общие опции для myisamchk


Опции, описываемые в этом разделе, могут использоваться для любого типа опера-
ций по обслуживанию таблиц, выполняемых утилитой myisamchk. В следующих после
этого разделах рассматриваются опции, имеющие отношение только к конкретным опе-
рациям, таким как проверка или восстановление таблиц.
• —help, -?. Отображает справочное сообщение и завершает работу.
4.6. Предотвращение аварий и восстановление системы 323

• —с1еЪид=опции_отладки, -# опции_отладки. Записывает отладочную информацию.


Строка опции_отладки часто выглядит как ' d: t : о, имя_файла'.
• — s i l e n t , -s. Режим минимального количества сообщений. Вывод данных только
в случае возникновения ошибок. Можно использовать -s дважды (-ss) для дос-
тижения максимального эффекта.
• --verbose, -v. Режим расширенных сообщений. Выводится больше информации.
Может использоваться вместе с -d и -е. Чтобы максимально увеличить объем вы-
ходных данных, -v указывается многократно (-vv, -vvv).
• — v e r s i o n , -V. Отображает данные о версии и завершает работу.
• —wait, -w. Если таблица заблокирована, не выдавать ошибку, а ожидать, пока
блокировка будет снята, прежде чем продолжить работу. Обратите внимание, что
если mysqld запущен с опцией — s k i p - e x t e r n a l - l o c k i n g , таблица может быть за-
блокирована только другой командой myisamchk.
Кроме того, с помощью опций —имя_переменной= значение можно устанавливать
следующие переменные:
Переменная Значение по умолчанию
decode_bits 9
f t_max_word_len Зависит от версии
ft_min_word_len 4
key_buffer_size 523264
myisam_block_size 1024
read_buffer_size 262136
sort_buffer_size 2097144
sort_key_blocks 16
write_buffer_size 262136

Устанавливать переменные можно и с помощью синтаксиса — s e t - v a r i a b l e =


имя переменной^значение или -0 имя_переменной= значение. Однако в версии MySQL
4.0 такой синтаксис уже устарел.
Изучить допустимые переменные myisamchk и их значения по умолчанию можно с
помощью опции myisamchk — h e l p :
• s o r t _ b u f f e r _ s i z e применяется, когда ключи исправляются путем их сортировки,
что далеко не редкость при использовании —recover.
• key_buffer_size применяется при проверке таблиц с помощью —extend-check
или при исправлении ключей путем их построчной вставки в таблицу (подобно
осуществлению обычных вставок).
Исправления через буфер ключей необходимы в следующих случаях:
• При использовании — s a f e - r e c o v e r .
• Когда временные файлы, необходимые для сортировки ключей, требуют в два (и
выше) раза больше места, чем создание файла ключей непосредственно. Чаще
всего это происходит, если в столбцах CHAR, VARCHAR или TEXT содержаться боль-
шие ключевые значения, поскольку во время операции сортировки их приходится
324 Глава 4. Администрирование баз данных

сохранять полностью. При наличии большого объема пространства для времен-


ных файлов и возможности исправления таблиц через сортировку, можно исполь-
зовать опцию —sort-recover.
Для операций по восстановлению таблиц посредством буфера ключей требуется зна-
чительно меньше пространства на диске, чем для проведения сортировки, однако в то же
время выполняются они намного медленнее.
Чтобы ускорить процесс восстановления таблиц, устанавливайте для переменных
key_buffer_size и sort_buffer_size значения, соответствующие приблизительно 25%
доступной памяти. Значения обеих переменных могут быть большими, поскольку за раз
используется только одна из них.
myisamblocksize - это размер, используемый для индексных блоков. Опция дос-
тупна, начиная с версии MySQL 4.O.O.
Переменные f t_min_word_len и f t_max_word_len доступны, также начиная с версии
MySQL 4.0.0, a f t s t o p w o r d f i l e - начиная с MySQL 4.0.19.
f t_min_word_len и f t_max_word_len обозначают минимальную и максимальную дли-
ну слова для индексов FULLTEXT. f t_stopword_f i l e указывает имя файла стоп-слов. Эти
опции необходимо устанавливать при описанных ниже обстоятельствах.
Если myisamchk используется для выполнения операции, изменяющей табличные ин-
дексы (такой как операция исправления или операция анализа), индексам FULLTEXT при-
сваиваются значения по умолчанию с полнотекстовыми параметрами для минимальной
и максимальной длины слов, а также для файла стоп-слов, до тех пор, пока не будут за-
даны другие значения. Это может привести к невыполнению запросов.
Проблема возникает из-за того, что эти параметры известны только серверу. В ин-
дексных файлах My ISAM они не сохранены. Чтобы избежать этой проблемы, когда изме-
нены значения для максимальной и минимальной длины слов или файла стоп-слов на
сервере, задайте утилите myisamchk те же самые, которые используются для mysqld, зна-
чения ft_min_word_len, ft_max_word_len и ft__stopword_file. Например, если для ми-
нимальной длины слова установлено значение 3, посредством myisamchk таблицу можно
восстановить следующим образом:
shell> myisamchk —recover —ft_min_word_len=3 имя_ та блицы. MYI
Для гарантии, что myisamchk и сервер будут использовать одинаковые значения для
полнотекстовых параметров, можно каждое из них разместить одновременно и в разделе
[mysqld], и в разделе [myisamchk] файла опций:
[mysqld]
ft__min_word_len=3
[myisamchk]
ft__min_word_len=3
Альтернативным вариантом для утилиты myisamchk является применение операторов
REPAIR TABLE, ANALYZE TABLE, OPTIMIZE TABLE И ALTER TABLE. Эти операторы ВЫПОЛНЯ-
ЮТСЯ сервером, которому известно, какие использовать значения для полнотекстовых
параметров.

4.6.2.3. Опции проверки для myisamchk


Утилита myisamchk поддерживает следующие опции, необходимые для проведения
операций по проверке таблиц:
4.6. Предотвращение аварий и восстановление системы 325

• —check, -с. Проверить таблицу на наличие ошибок. Представляет собой опера-


цию по умолчанию, если только не задается опция, явно указывающая тип необ-
ходимой операции.
• —-check-only-changed, -С. Проверить только таблицы, которые были изменены с
момента запуска последней проверки.
• —extend-check, -e. Расширенная проверка таблицы. Процесс происходит очень
медленно, если таблица содержит большое количество индексов. Эта опция
должна использоваться только в крайних случаях. Обычно проверки при помощи
myisamchk или myisamchk —medium-check вполне достаточно, чтобы определить
наличие любых ошибок в таблице.
При использовании —extend-check и доступности большого объема памяти, ус-
тановка высокого значения для переменной key_buffer_size позволяет ускорить
выполнение операций по исправлению.
• —fast, -F. Проверить только таблицы, которые не были закрыты надлежащим
образом.
• —force, -f. Выполнять исправления автоматически, если myisamchk находит хоть
одну ошибку в таблице. Тип исправления такой же, как и тот, что указан в опции
—repair или -г.
• —information, -i. Выводить статистические данные по проверенной таблице.
• —medium-check, -m. Выполняет более быструю проверку, чем —extend-check.
Находит только 99,99% ошибок, но этого должно оказаться вполне достаточно в
большинстве случаев.
• --read-only, -Т. Не отмечать таблицу как проверенную. Может пригодиться, если
с помощью myisamchk проверяется таблица, которая используется каким-либо
другим приложением, не применяющим блокировку (например, mysqld, запущен-
ным с опцией —skip-external-locking).
• —update-state, -U. Сохранять информацию о дате проверки или о повреждениях
таблицы в файле .MYI. Опцию следует применять, чтобы извлечь максимальную
пользу из —check-only-changed, и не следует - когда таблица используется сер-
вером mysqld, который запущен с опцией --skip-external-locking.

4.6.2.4. Опции восстановления для myisamchk


Утилита myisamchk поддерживает следующие опции, необходимые для проведения
операций по восстановлению таблиц:
• —backup, -В. Сделать резервную копию файла .MYD в виде имя^файла- время .ВАК.
• —character-sets-dir=nyTb. Каталог, в котором находятся наборы символов. См.
раздел 4.7.1.
• —correct-checksum. Откорректировать данные контрольной суммы для таблицы.
• --data-file-length=#, -D #. Максимальный размер (длина) файла данных (при
повторном создании такого файла, когда этот файл уже полностью "заполнен").
• —extend-check, -e. Выполнить операцию по исправлению с восстановлением
каждой возможной строки из файла данных. Обычно при этом восстанавливается
326 Глава 4. Администрирование баз данных

и масса ненужных строк. Используйте эту опцию только тогда, когда ситуация
становится полностью безвыходной.
• —force, -f. Вместо аварийного прекращения работы перезаписывать старые вре-
менные файлы (то есть файлы с именами наподобие имя__таблицыЛШ)).
• ~keys-used=#, -k #. Для myisamchk значение опции указывает, какие индексы
обновлять. Каждый двоичный бит значения опции соответствует индексу табли-
цы, где первый индекс - это бит 0. Для isamchk значение опции означает, что об-
новлять следует только первых # индексов. В обоих случаях значение 0 блокирует
обновления для всех индексов, что может использоваться для ускорения вставок.
Отключенные индексы могут быть активизированы снова при помощи myisamchk
-г или isamchk -r.
• —no-symlinks, - I . He учитывать символические ссылки. Обычно myisamchk ис-
правляет таблицу, на которую указывает символическая ссылка. Данная опция не
существует, начиная с версии MySQL 4.O. В версиях 4.0 и выше символические
ссылки не удаляются во время операций по исправлению.
• —parallel-recover, -p. Применяет те же приемы, что и -г или -п, но создает все
ключи параллельно, используя разные потоки. Опция была добавлена в MySQL
4.0.2. Пребывает на стадии альфа-тестирования. Используйте исключительно
на своп страх и риск!
• — quick, -q. Ускоряет операции по восстановлению без изменения файла данных.
Можно задавать двойную опцию -q, что заставит myisamchk изменять исходный
файл данных в случае, если ключи дублируются.
• —recover, -r. Исправляет почти все ошибки, за исключением проблем с уни-
кальными ключами, которые таковыми не являются (в таблицах ISAM и My ISAM это
крайне редкий случай). Если необходимо восстановить таблицу, данная опция яв-
ляется первой, которую следует использовать. Попробуйте применить -о, только
если myisamchk выдает сообщение о том, что таблица не может быть восстановле-
на посредством -г (даже если это произойдет, что маловероятно, файл данных
при этом останется незатронутым).
• —safe-recover, -о. Выполняет операцию по исправлению с помощью старого
метода восстановления, при котором считываются все строки подряд и на основе
найденных строк осуществляется обновление всех индексных деревьев. Такая
операция выполняется на порядок медленнее, чем при использовании -г, но по-
могает решить пару маловероятных проблем, с которыми опция -г справиться не
может. Также при таком методе требуется намного меньше пространства на дис-
ке, нежели когда применяется -г. Обычно сначала всегда используется опция -г,
и только если результат будет неудовлетворительным, используется опция -о.
При наличии большого доступного объема памяти следует увеличить значение
key_buffer__size.
• —set-character-set=niwi. Изменяет таблицу символов, используемую при по-
строении индексов.
• —sort-recover, -n. Заставляет myisamchk использовать метод сортировки для
преобразования ключей, даже если слишком большой размер временных файлов
нежелателен.
4.6. Предотвращение аварий и восстановление системы 327

• --tmpdir=nyrb, - t путь. Путь к каталогу, который будет использоваться для хра-


нения временных файлов. Если данная опция не задана, myisamchk берет значение
переменной окружения TMPDIR. Начиная с версии MySQL 4.1, в tmpdir можно
указывать сразу несколько путей к каталогам, которые будут использоваться по-
очередно по циклическому принципу для создания временных файлов. В качестве
разделительного символа между именами каталогов в Unix служит двоеточие
(':'), а в Windows, NetWare и OS/2 - точка с запятой (';').
• --unpack, -u. Распаковать таблицу, которая была упакована с помощью
myisampack.

4.6.2.5. Другие ОПЦИИ ДЛЯ myisamchk


Помимо опций для проверки и восстановления таблиц утилита myisamchk поддержи-
вает и другие опции:
• --analyze, -а. Анализировать распределение ключей. Это повышает эффектив-
ность соединений, позволяя оптимизатору более правильно выбирать порядок, в
котором следует соединять таблицы, и ключи, которые должны при этом исполь-
зоваться. Для получения информации по распределению ключей воспользуйтесь
командой myisamchk —description —verbose имя_таблицы или оператор SHOW
KEYS FROM имя^таблицы.
• —description, -d. Отображает информацию описательного характера о таблице.
• —set-auto-increment[^значение], -А[значение]. Задает начало нумерации
AUTO_INCREMENT для новых записей с определенного значения (или большего, если
записи с таким значением AUTO_INCREMENT уже существуют). Если значение не
указано, то в качестве первого значения для AUTO_INCREMENT будет использоваться
наибольшее на данный момент в таблице значение плюс один.
• —sort-index, -S. Сортирует блоки индексного дерева в порядке от наибольшего
к меньшему. Это оптимизирует операции поиска и ускоряет операции сканирова-
ния по ключу.
• —sort-records=#, -R #. Сортирует записи в соответствии с определенным индек-
сом. Это повышает степень локализации данных и может ускорить выполнение
интервальных операций SELECT и ORDER BY, использующих данный индекс. (При
первом запуске этой опции сортировка может выполняться очень медленно.) Для
определения номеров индексов применяйте оператор SHOW KEYS, который отобра-
жает индексы таблиц именно в том порядке, в каком их видит myisamchk. Нуме-
рация индексов начинается с 1.

4.6.2.6. Использование памяти утилитой myisamchk


При работе с утилитой myisamchk распределение памяти является важным вопросом.
Утилита myisamchk не использует большего, чем задано в опции -0, объема памяти. В
случае применения myisamchk для очень больших таблиц, первым делом потребуется
продумать, какой объем памяти при этом потребуется. Присваиваемое по умолчанию
значение для выполнения операций по исправлению составляет приблизительно
3 Мбайт. Установка больших значений ускоряет работу myisamchk. Например, при нали-
чии более чем 32 Мб ОЗУ можно использовать и такие опции (помимо всех других зада-
ваемых опций):
328 Глава 4. Администрирование баз данных

shell> myisamchk -О sort=16M -0 кеу=16М -О read=lM -О write=lM ...


Значения -О sort=16M в большинстве случаев будет вполне достаточно.
Помните о том, что myisamchk использует временные файлы в TMPDIR. Если TMPDIR
указывает на файловую систему в ОЗУ, ошибки типа "недостаточно памяти" не исклю-
чены. Если подобное произойдет, сделайте так, чтобы TMPDIR указывал на каталог в
файловой системе с большим свободным пространством и перезапустите myisamchk.
Для выполнения операций по исправлению myisamchk также требует большого объе-
ма доступного дискового пространства:
• Понадобится пространство размером как два файла данных (для исходного файла
и его копии). При выполнении операции по исправлению с помощью —quick та-
кое пространство не требуется, так как повторно создается только индексный
файл. Однако оно необходимо в файловой системе, где находится исходный
файл данных, поскольку копия создается в том же каталоге, в котором хранится
оригинал.
• Понадобится пространство для нового индексного файла, который заместит собой
старый. В самом начале операции по восстановлению старый индексный файл
усекается, поэтому занимаемое им пространство можно игнорировать. Дополни-
тельное место потребуется в той файловой системе, в которой находится исход-
ный индексный файл.
• При использовании —recover или --sort-recover (но не —safe-recover) пона-
добится дополнительное пространство под буфер сортировки. Необходимый объ-
ем такого пространства вычисляется следующим образом:
{наиболыпий_ключ + длина_указателя_строки) * количество_строк * 2
Узнать длину ключей и длина_указателя_строки можно с помощью myisamchk
-dv имя_таблицы. Это пространство выделяется во временном каталоге (указан-
ном с помощью TMPDIR или —tmpdiг=луть).
При возникновении проблем, связанных с недостаточным объемом пространства
на диске, во время выполнения операций по восстановлению, попробуйте указать
—safe-recover вместо —recover.

4.6.2.7. Использование myisamchk для восстановления после аварий


При запуске mysqld с опцией —skip-external-locking (являющейся опцией по
умолчанию в некоторых системах, например, в Unix) надежность проверки таблицы по-
средством myisamchik, когда эта же таблица используется сервером mysqld, не гаранти-
руется. Если есть абсолютная уверенность в том, что никто не попытается получить дос-
туп к таблицам через mysqld в то время, когда будет работать myisamchk, тогда единст-
венное, что нужно сделать перед проверкой таблиц, это выполнить команду mysqladmin
flush-tables. Если такой уверенности нет, следует остановить mysqld на время, пока
будут проверяться таблицы. В случае запуска myisamchik тогда, когда таблицы обнов-
ляются сервером mysqld, может появиться предупреждение о том, что таблица повреж-
дена, даже если на самом деле это не так.
При отсутствии опции —skip-external-locking использовать myisamchik для про-
верки таблиц можно в любое время. В таком случае, во время проверки всем клиентам,
пытающимся обновить таблицу, придется ожидать, пока myisamchik не будет готова
продолжить работу.
4.6. Предотвращение аварий и восстановление системы 329

Если myisamchik применяется в целях исправления или оптимизации таблиц, всегда


обязательно позаботьтесь о том, чтобы во время проведения этих операций данная таб-
лица не использовалась сервером mysqld (это также относится и к случаям, когда приме-
няется опция —skip-external-locking). Необходимо, если не приостановить работу
mysqld, то, по крайней мере, выполнить команду mysqladmin flush-tables, прежде чем
запускать myisamchik. При одновременном доступе со стороны сервера и со стороны
myisamchik не исключено повреждение таблиц.
В данном разделе описывается, как проверить базы данных MySQL на наличие в них
повреждений и что делать в случаях, когда повреждения данных были обнаружены. Ес-
ли повреждение таблиц случается достаточно часто, следует попытаться выяснить при-
чину, по которой это происходит. См. раздел А.4.2.
В разделе, посвященном таблицам My ISAM, описываются причины, по которым может
произойти повреждение данных в таблице. См. раздел 8.1.4.
Для проведения операций по восстановлению после аварий чрезвычайно важно по-
нимать, что каждой таблице My ISAM с именем имя_таблицы в базе данных соответствуют
три файла в каталоге базы данных:
Файл Назначение
имя_таблицы. f rm Файл определения (формата).
имя_ та блицы. MY D Файл данных.
имя_ та блицы. MY I Файл индекса.
Каждый из этих трех файлов подвержен своему типу повреждений, но чаще всего
проблемы возникают с файлами данных и индексными файлами.
Сначала myisamchik создает копию файла данных .MYD построчным методом. Этап
исправления завершается удалением старого файла .MYD и присвоением новому файлу
имени исходного файла. При использовании —quick утилита myisamchik не создает
временный файл .MYD, предполагая, что файл .MYD является корректным, и поэтому ге-
нерирует только новый индексный файл, не затрагивая файл .MYD. Такой способ безопа-
сен, поскольку myisamchik автоматически определяет, поврежден ли файл .MYD, и если
это так, тут же прекращает операцию по исправлению. Для myisamchik также можно
указывать опцию —quick дважды. В этом случае при возникновении некоторых ошибок
(таких как, например, дублирование ключа) myisamchik не будет аварийно прекращать
работу, а вместо этого попытается разрешить эти ошибки путем изменения файла .MYD.
Обычно применять две опции —quick полезно тогда, когда свободного пространства на
диске недостаточно для проведения стандартной операции по исправлению. В таком
случае необходимо, по крайней мере, выполнить резервное копирование, прежде чем
запускать myisamchik.

4.6.2.8. Как проверить таблицы MyiSAM на наличие ошибок


Для проверки таблицы My ISAM используются следующие команды:
• myisamchk имя_таблицы. Эта опция позволяет обнаружить 99,9% всех ошибок.
Она не находит только повреждения, имеющие непосредственное отношение к
файлу данных (которые маловероятны). Чтобы проверить таблицу, обычно следу-
ет запустить myisamchk без опций или с одной из опций -s или —silent.
330 Глава 4. Администрирование баз данных

• myisamchk -m имя_таблицы. Эта опция позволяет найти 99,999% всех ошибок. Она
сначала отдельно проверяет все индексные записи на наличие ошибок, а затем
просматривает все строки подряд. После этого вычисляется контрольная сумма
для всех ключей во всех строках, которая сопоставляется с контрольной суммой
ключей в индексном дереве.
• myisamchk -e имя_таблицы. С помощью этой опции проводится полная и тща-
тельная проверка абсолютно всех данных (-е означает расширенную проверку).
Эта опция осуществляет проверочное считывание каждого ключа для каждой
строки, проверяя, действительно ли ключи указывают на те строки, на которые
нужно. Для больших таблиц с множеством ключей выполнение такой операции
может занять много времени. Обычно myisamchk останавливается, обнаружив
первую же ошибку. Чтобы получать больше данных, можно добавить опцию
—verbose (-v). В таком случае myisamchk сможет не останавливаться до тех пор,
пока количество ошибок не достигнет максимального числа 20.
• myisamchk -e -i имя_таблицы. Схожа с предыдущей командой, но опция -i вы-
нуждает myisamchk отображать также и некоторые статистические данные.
В большинстве случаев просто запустить myisamchk, не указывая никаких других ар-
гументов, кроме имени таблицы, оказывается вполне достаточно для проведения про-
верки.

4.6.2.9. Как исправлять таблицы


В данном разделе описано, как использовать myisamchk для таблиц MylSAM (файлы с
расширением .MYI и .MYD). Для таблиц ISAM (файлы с расширением .ISM и .ISD) вместо
myisamchk следует использовать утилиту isamchk. Общие принципы применения обеих
утилит одинаковы.
В версии MySQL 3.23.16 и выше для проверки и исправления таблиц MylSAM можно
(и нужно) использовать операторы CHECK TABLE и REPAIR TABLE.
Признаками того, что таблица повреждена, служат неожиданное прерывание обра-
ботки запросов и появление ошибок, таких как:
• Файл иыя__таблицы. f rm заблокирован для изменения.
• Невозможно найти файл имя_таблицы.Ш1 (номер ошибки: ###).
• Неожиданный конец файла.
• Файл записей поврежден.
• Получена ошибка ### от обработчика таблицы.
Для получения более подробной информации об ошибке, можно запустить perror
###, где ### - номер ошибки. Ниже представлены выдаваемые perror номера наиболее
распространенных ошибок, свидетельствующих о проблемах с таблицей, а также их зна-
чение:
shell> perror 126 127 132 134 135 136 141 144 145
126 = Index f i l e is crashed / Wrong f i l e format
Индексный файл поврежден / Неправильный формат файла
127 = Record-file is crashed
Файл записей поврежден
132 = Old database file
Файл из старой базы данных
4.6. Предотвращение аварий и восстановление системы 331

134 = Record was already deleted (or record f i l e crashed)


Запись уже удалена (или файл записей поврежден)
135 = No more room in record f i l e
В файле записей больше нет места
136 = No more room in index f i l e
В индексном файле больше нет места
141 = Duplicate unique key or constraint on write or update
Дублирование уникального ключа или ограничения по записи
или по обновлению
144 = Table is crashed and l a s t repair failed
Таблица повреждена и последняя операция по исправлению не была успешной
145 = Table was marked as crashed and should be repaired
Таблица помечена как поврежденная и подлежит восстановлению
Обратите внимание, что ошибки с номерами 135 ("В файле записей больше нет
места") и 136 ("В индексном файле больше нет места") не являются ошибками, от кото-
рых можно избавиться с помощью простой операции исправления. В таком случае при-
дется воспользоваться оператором ALTER TABLE, чтобы увеличить значения табличных
ОПЦИЙ MAX_ROWS И AVG_ROW_LENGTH:
ALTER TABLE имя_таблицы MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;

Если текущие значения опций таблицы не известны, воспользуйтесь оператором SHOW


CREATE TABLE имя_таблицы.
Остальные ошибки требуют только выполнения операции по исправлению.
myisamchk обычно может определить и исправить большую часть встречающихся непо-
ладок.
Процесс исправления включает до четырех стадий, которые описаны ниже. Прежде
чем приступить к выполнению операции по исправлению, следует изменить местополо-
жение каталога базы данных и проверить права доступа к файлам таблиц. В среде Unix
убедитесь, что они доступны по чтению для пользователя, от имени которого запускает-
ся mysqld (а также вам, поскольку вам понадобится доступ к проверяемым файлам). Ес-
ли появится необходимость в изменении файлов, у вас также должен быть к ним и дос-
туп по записи.
Опции myisamchk и isamchk для обслуживания таблиц описаны ранее в разделе 4.6.2.
Ниже рассматриваются случаи, когда предложенные опции не действуют или если
появляется необходимость пользоваться расширенными возможностями, предоставляе-
мыми утилитами myisamchk и isamchk.
При намерении осуществлять исправление таблиц из командной строки, первым де-
лом обязательно следует остановить сервер. Обратите внимание, что когда mysqladmin
shutdown выполняется на удаленном сервере, сервер mysqld еще некоторое время после
возврата mysqladmin продолжает функционировать, пока не будут остановлены все за-
просы и все ключи не будут записаны на диск.
Стадия 1: проверка таблиц
Запустите myisamchk * .MYI или, при наличии времени, myisamchk -e * .MYI. Исполь-
зуйте опцию -s (режим минимальной выдачи сообщений), чтобы излишняя информация
не отображалась.
Если сервер mysqld остановлен, следует применить опцию —update-state, чтобы
myisamchk начала отмечать таблицы как 'checked' ('проверенные').
332 Глава 4. Администрирование баз данных

Исправлению подлежат только те таблицы, для которых myisamchk выдает ошибку. В


этом случае переходите к стадии 2.
При получении "странных" ошибок (таких как "недостаточно памяти") или аварий-
ном прекращении работы myisamchk переходите к стадии 3.
Стадия 2: простое безопасное исправление
| На заметку!
щ Чтобы максимально ускорить операцию по исправлению, необходимо при запуске myisamchk и
р, isamchk установить переменные s o r t _ b u f f e r _ s i z e и k e y _ b u f f e r _ s i z e так, чтобы значение
'%, каждой из них соответствовало 25% доступной памяти.

Первым делом попробуйте запустить myisamchk -r -q имя_таблицы (где -г -q обо-


значает режим быстрого восстановления). Это приведет к попытке исправить индексный
файл без изменения файла данных. Если файл данных содержит всю необходимую ин-
формацию, и удаленные ссылки указывают на те, что нужно позиции в файле данных,
опция должна сработать, в результате чего таблица будет исправлена. Тогда можно пе-
реходить к исправлению следующей таблицы. В противном случае потребуется выпол-
нить перечисленные ниже действия:
1. Подготовьте резервную копию файла данных, прежде чем продолжать.
2. Запустите myisamchk -r имя_таблицы (где -г обозначает режим восстановления).
Это очистит файл данных от некорректных и удаленных записей, а индексный
файл будет создан заново.
3. Если вызов myisamchk -г имя_ та блицы не поможет, воспользуйтесь—safe-recover
имя_таблицы. Режим безопасного восстановления использует старый метод вос-
становления, справляющийся с несколькими случаями, с которыми стандартный
режим восстановления справиться не может (однако старый метод медленнее).
При получении "странных" ошибок (таких как "недостаточно памяти") или аварий-
ном прекращении работы myisamchk переходите к стадии 3.
Стадия 3: исправления обычной сложности
Доходить до этой стадии следует только в тех случаях, когда первый блок размером
16 Кбайт в индексном файле запорчен или содержит некорректную информацию, либо
же если индексный файл вообще отсутствует. В таком случае потребуется создать новый
индексный файл. Для этого необходимо выполнить следующие шаги:
1. Переместите файл данных в какое-нибудь безопасное место.
2. Используйте файл описания таблицы, чтобы создать новые (пустые) файл данных
и индексный файл.
shell> mysql имя_таблицы
mysql> SET AUTOCOMMIT=1;
mysql> TRUNCATE TABLE имя_таблицы;
mysql> quit
Если в существующей версии MySQL оператор TRANCATE TABLE не доступен, вме-
сто него используйте DELETE FROM имя_таблицы.
3. Скопируйте старый файл данных в только что созданный новый файл данных. (Не
стоит просто переносить содержимое старого файла данных в новый; лучше со-
хранить копию файла данных на случай, если что-нибудь пойдет не так.)
4.6. Предотвращение аварий и восстановление системы 333

Вернитесь к стадии 2. Теперь опция myisamchk -r -q имя_ та блицы должна работать.


(Тем не менее, превращать все это в бесконечный цикл не следует.)
Начиная с версии MySQL 4.0.2, также можно использовать оператор REPAIR TABLE
имя_таблицы USE_FRM, который выполняет всю описанную процедуру автоматически.
Стадия 4: исправление повышенной сложности
Доходить до этой стадии следует только, если файл описания . f rm тоже запорчен.
Такое не должно случаться никогда, поскольку после создания таблицы файл описания
не изменяется.
1. Восстановите файл описания из резервной копии и вернитесь к стадии 3. Также
можно восстановить индексный файл и вернуться к стадии 2. В последнем случае
начинать следует с myisamchk -r.
2. Если резервная копия отсутствует, но вы точно знаете, как была создана таблица,
создайте копию таблицы в другой базе данных. Удалите новый файл данных, за-
тем перенесите файл описания . f rm и индексный файл из той другой базы данных
в поврежденную базу данных. Тем самым вы получите новый файл описания и
новый индексный файл, а файл данных .MYD при этом остается незатронутым.
Вернитесь к стадии 2 и попробуйте восстановить индексный файл.

4.6.2.10. Оптимизация таблиц


Чтобы объединить фрагментированные записи и ликвидировать растрачиваемое впус-
тую пространство, появляющееся после удаления или обновления записей, запустите
myisamchk в режиме восстановления:
shell> myisamchk -r имя_таблицы
Таким же образом таблицу можно оптимизировать и с помощью SQL-оператора
OPTIMIZE TABLE. Этот оператор исправляет таблицу, анализирует ключи, а также выпол-
няет сортировку в индексном дереве, что ускоряет поиск ключей. Возможность нежела-
тельного взаимодействия между утилитой и сервером исключается, поскольку когда
используется OPTIMIZE TABLE, сервер выполняет всю работу сам.
myisamchk также предлагает и ряд других опций, которые можно применять для по-
вышения эффективности таблицы:
• -S, —sort-index
• -R индексное_число, —sort-лесоЫБ=индексное_число
• -а,—analyze
Подробное описание этих опций можно найти в разделе 4.6.2.1.

4.6.3. Установка графика обслуживания таблиц


Конечно, лучше выполнять проверку таблиц регулярно, а не ждать, когда появятся
проблемы. Один из способов проверить и исправить таблицу My ISAM - это воспользо-
ваться операторами CHECK TABLE и REPAIR TABLE, которые доступны, начиная с версии
MySQL 3.3.16.
Другой способ - это использовать утилиту myisamchk. В целях профилактики можно
применять myisamchk -s. Опция -s (сокращенный вариант - - s i l e n t ) заставляет
334 Глава 4. Администрирование баз данных

myisamchk работать в режиме минимальной выдачи сообщений, при котором сообщения


отображаются только в случае возникновения ошибки.
Совсем не помешает проверять таблицы и при запуске сервера. Например, обычно во
время обновления, когда выполняется перезагрузка машины, то без проверки всех таб-
лиц, которых это хоть как-то могло коснуться, обойтись нельзя (такие таблицы считают-
ся "потенциально поврежденными"). Для автоматической проверки таблиц MylSAM за-
пустите сервер с опцией —myisam-recover, доступной, начиная с версии MySQL 3.23.25.
Если версия сервера старая и не поддерживает указанную опцию, можно к mysqldsafe
добавить тест, который запустит myisamchk для проверки всех таблиц, которые были
изменены за последние 24 часа, если только после перезагрузки не остался старый файл
.pid (файл идентификатора процесса). Обычно файл .pid создается mysqld при запуске
и удаляется в случае нормального завершения работы сервера. Наличие файла .pid во
время запуска системы указывает на то, что работа mysqld не была завершена корректно.
А еще лучше - проверить таблицы, дата последнего изменения которых более ран-
няя, чем у файла .pid.
Также следует проверять таблицы регулярно даже тогда, когда система функциони-
рует нормально. В компании MySQL AB раз в неделю запускается задание сгоп, которое
провернет все важные таблицы; при этом в файле crontab используется такая строка:
35 0 * * 0 /путь/к/myisamchk —fast —silent /путь/к/каталогу_данных/*/* .MYI
В этом случае выводится информация обо всех поврежденных таблицах, что позво-
ляет, при необходимости, изучить и исправить их.
Поскольку неожиданных повреждений таблиц (повреждение таблиц не по причинам
проблем с оборудованием) за последние несколько лет компании MySQL AB не проис-
ходило (и это истинная правда!), то выполнения проверки один раз в неделю для нас
более чем достаточно.
Мы рекомендуем сначала запускать myisamchk -s каждую ночь на всех таблицах,
которые обновлялись за последние 24 часа до тех пор, пока вы не станете доверять
MySQL настолько, насколько этой системе доверяют в MySQL AB.
Обычно таблицы MySQL в частом обслуживании не нуждаются. В случае изменения
таблиц с динамическим размером строк (таблиц, содержащих столбцы VARCHAR, BLOB или
TEXT) или при наличии таблиц с большим количеством удаленных строк может время от
времени понадобиться дефрагментация либо восстановление пространства из таблиц
(возможно, раз в месяц).
Сделать это можно на таких таблицах с помощью оператора OPTIMIZE TABLE. Или же,
если есть возможность приостановить сервер mysqld на некоторое время, перейдите в
каталог данных и выполните следующую команду (пока сервер остановлен):
shell> myisamchk -r -s —sort-index -0 sort_buffer_size=16M */*.MYI
Аналогичная команда используется и для таблиц ISAM:
shell> isamchk -г -s —sort-index -0 sort_buffer_size=16M */*.ISM

4.6.4. Как получить информацию о таблице


Чтобы получить описание таблицы или статистику по ней, используйте представлен-
ные в данном разделе команды. Некоторая информация более подробно рассматривается
позже:
4.6. Предотвращение аварий и восстановление системы 335

• myisamchk -d имя_таблицы. Запускает myisamchk в "режиме описания" для со-


ставления описания таблицы. В случае, когда сервер MySQL запускался с опцией
—skip-external locking, myisamchk может выдать сообщение об ошибке для
таблицы, которая обновляется во время выполнения утилиты. Однако, поскольку
myisamchk не изменяет таблицу в "режиме описания", риска повреждения данных нет.
• myisamchk -d -v имя_таблицы. При добавлении -v утилита myisamchk запускается
в режиме расширенных сообщений, и будет выводить более подробную информа-
цию о том, что она делает.
• myisamchk - e i s имя_таблицы. Отображает только наиболее важную информацию
из таблицы. Эта операция выполняется медленно, поскольку считывать приходит-
ся всю таблицу целиком.
• myisamchk - e i v имя_таблицы. Подобна опции - e i s , но только еще и информирует
о том, какие выполняются действия.
Ниже представлен пример выходных данных для некоторых из этих команд. Размеры
файла данных и индексного файла рассматриваемой таблицы следующие:
-rw-rw-r-- I monty tcx 317235748 Jan 12 17:30 company.MYD
-rw-rw-r— 1 davida tcx 96482304 Jan 12 18:35 company.MYM
Пример выходных данных myisamchk -d:
MylSAM file: company.MYI
Record format: Fixed length
Data records: 1403698 Deleted blocks: 0
Recordlength: 226
table description:
Key Start Len Index Type
1 2 8 unique double
2 15 10 multip. text packed stripped
3 219 8 multip. double
4 63 10 multip. text packed stripped
5 167 2 multip. unsigned short
6 177 4 multip. unsigned long
7 155 4 multip. text
8 138 4 multip. unsigned long
9 177 4 multip. unsigned long
193 1 text
Пример выходных данных myisamchk -d -v:
MylSAM file: company
Record format: Fixed length
File-version: 1
Creation time: 1999-10-30 12:12:51
Recover time: 1999-10-31 19:13:01
Status: checked

Data records: 1403698 Deleted blocks: 0


Datafile parts: 1403698 Deleted data: 0
Datafile pointer (bytes): 3 Keyfile pointer (bytes): 3
Max datafile length: 3791650815 Max keyfile length: 4294967294
Recordlength: 226
336 Глава 4. Администрирование баз данных

table description:
Key Start Len Index Type Rec/key Root Blocksize
1 2 8 unique double 1 15845376 1024
2 15 10 multip. text packed stripped 2 25062400 1024
3 219 8 multip. double 73 40907776 1024
4 63 10 multip. text packed stripped 5 48097280 1024
5 167 2 multip. unsigned short 4840 55200768 1024
6 177 4 multip. unsigned long 1346 65145856 1024
7 155 4 multip. text 4995 75090944 1024
8 138 4 multip. unsigned long 87 85036032 1024
9 177 4 multip. unsigned long 178 96481280 1024
193 1 text
Пример выходных данных myisamchk -eis:
Checking MylSAM file: company
Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4
Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4
Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4
Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3
Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4
Total: Keyblocks used: 98% Packed: 17%
Records : 1403698 M.recordlength:: 226
Packed: 0%
Recordspace used: 100% Empty space: 0%
Blocks/Record: 1.00
Record blocks: 1403698 Delete blocks: 0
Recorddata: 317235748 Deleted data: 0
Lost space: 0 Linkdata: 0
User time 1626.51, System time 232.36
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 627, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 639, Involuntary context switches 28966
Пример выходных данных myisamchk -eiv:
Checking MylSAM file: company
Data records: 1403698 Deleted blocks: 0
- check file-size
- check delete-chain
block_size 1024:
index 1:
index 2:
index 3:
index 4:
index 5:
index 6:
index 7:
4.6. Предотвращение аварий и восстановление системы 337

index 8:
index 9:
No recordlinks
- check index reference
- check data record references index: 1
Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4
- check data record references index: 2
Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4
- check data record references index: 3
Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4
- check data record references index: 4
Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3
- check data record references index: 5
Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 6
Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 7
Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 8
Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 9
Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4
Total: Keyblocks used: 9% Packed: 17%
- check records and index references
[LOTS OF ROW NUMBERS DELETED]
Records: 1403698 M.recordlength: 226 Packed: 0%
Recordspace used: 100% Empty space: 0% Blocks/Record: 1.00
Record blocks: 1403698 Delete blocks: 0
Recorddata: 317235748 Deleted data: 0
Lost space: 0 Linkdata: 0
User time 1639.63, System time 251.61
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0
Blocks in 4 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 10604, Involuntary context switches 122798
Н и ж е дается объяснение типов выдаваемой myisamchk информации. "Keyfile" отно-
сится к индексному файлу. "Record" (запись) и "row" (строка) являются синонимами.
• MylSAM file. И м я (индексного) файла MylSAM.
• File-version. Версия формата MylSAM. Н а настоящий момент всегда 2.
• Creation time. Когда в последний раз восстанавливался индексный файл/файл
данных.
• Data records. Количество записей в таблице.
• Deleted blocks. Количество удаленных блоков, которые по-прежнему имеют за-
резервированное для них пространство. М о ж н о оптимизировать таблицу, чтобы
свести такое пространство к минимуму. См. раздел 4.6.2.10.
338 Глава 4. Администрирование баз данных

• Datafile parts. Для динамического формата записей это означает количество


имеющихся блоков данных. Для оптимизированной таблицы, не содержащей
фрагментированных записей, это то же самое, что Data records.
• Deleted data. Количество байт удаленных данных, которые не восстанавлива-
лись. Можно оптимизировать таблицу, чтобы свести такое пространство к мини-
муму. См. раздел 4.6.2.10.
• Datafile pointer. Размер (в байтах) указателя файла данных. Обычно это 2, 3, 4
или 5 байт. Большинство таблиц работает с 2 байтами, но пока управлять данным
значением из MySQL невозможно. Для фиксированных таблиц - это адрес записи,
для динамических таблиц - адрес байта.
• Keyf i l e pointer. Размер (в байтах) указателя индексного файла. Обычно значе-
ние соответствует 1, 2 или 3 байтам. Большинство таблиц работает с 2 байтами,
но этот размер вычисляется MySQL автоматически. Это всегда адрес блока.
• Max datafile length. Насколько большим может быть размер файла данных таб-
лицы (в байтах).
• Max keyf i l e length. Насколько большим может быть размер индексного файла
(в байтах).
• Recordlength. Объем занимаемого каждой отдельной записью пространства
(в байтах).
• Record format. Формат, используемый для хранения табличных строк. В предло-
женных выше примерах использовался формат Fixed length. Другие возможные
форматы - Compressed и Packed.
• table description. Список всех ключей в таблице. Для каждого ключа myisamchk
отображает некоторую информацию более низкого уровня:
• Key. Номер данного ключа.
• Start. Где в записи начинается данная часть индекса.
• Len. Длина данной части индекса. Для упакованных чисел это значение всегда
должно соответствовать полной длине столбца. Для строк это значение может
быть меньше полной длины индексированного столбца, поскольку есть
возможность проиндексировать префикс строкового столбца.
• Index. Допустимо ли в индексе многократное повторение значения ключа. Ти-
пы значений - unique и multiple.
• Туре. Тип данных в данной части индекса. Это тип данных MylSAM. Возможные
значения - packed, stripped или empty.
• Root. Адрес корневого индексного блока.
• Blocksize. Размер каждого индексного блока. По умолчанию составляет 1024,
но значение может быть изменено во время компиляции в случае построения
MySQL из исходного кода.
• Rec/key. Это статистическое значение, используемое оптимизатором. Оно обо-
значает число записей на одно значение для данного ключа. Уникальному клю-
чу всегда соответствует значение 1. Значение можно обновить после загрузки
таблицы (или внесения в нее значительных изменений) с помощью myisamchk -a.
Если его вообще не обновлять, по умолчанию будет присвоено значение 30.
4.6. Предотвращение аварий и восстановление системы 339

В таблице, рассматриваемой в примерах, девятому индексу соответствуют две


строки table description. Это означает то, что данный индекс не является уни-
кальным, а состоит из двух частей.
• Keyblocks used. Процент используемых ключей. Сразу после реорганизации таб-
лицы с помощью myisamchk (как и в случае с таблицей, которая рассматривалась в
примерах) значения крайне высоки (очень близки к теоретическому максимуму).
• Packed (первое вхождение). MySQL пытается упаковать ключи с общим суффик-
сом. Может использоваться только для индексов в столбцах CHAR, VARCHAR или
DECIMAL. Для длинных индексованных строк, имеющих схожие части слева, это
позволяет существенно сократить объем занимаемого ими пространства. В треть-
ем приводимом выше примере четвертый ключ включает 10 символов, и зани-
маемое им пространство уменьшено на 60%.
• Max levels. Насколько глубоким является В-дерево для данного ключа. Для
больших таблиц с длинными ключами значения Max levels будут высокими.
• Records. Количество строк в таблице.
• M.recordlength. Средняя длина записи. Это точная длина для таблиц с записями
фиксированной длины, потому что в таких таблицах все записи имеют одинако-
вую длину.
• Packed (второе вхождение). MySQL удаляет пробелы в конце строк. Значение
Packed обозначает процент сэкономленного этим пространства.
• Recordspace used. Какой процент файла данных используется.
• Empty space. Какой процент файла данных не используется.
• Blocks /Record. Среднее число блоков, приходящихся на одну запись (то есть ко-
личество ссылок, из которых состоит фрагментированная запись). Для таблиц
фиксированного формата данное значение всегда составляет 1.0. Оно должно ос-
таваться близким к 1.0 настолько, насколько это возможно. Если значение стано-
вится слишком большим, можно приступать к реорганизации таблицы.
• Recordblocks. Количество используемых блоков (ссылок). Для фиксированного
формата это значение будет совпадать с количеством записей.
• Deleteblocks. Количество удаленных блоков (ссылок).
• Recorddata. Сколько байтов в файле данных используется.
• Deleted data. Сколько байтов в файле данных удалено (не используется).
• Lost space. Если после обновления запись становится короче, некоторое про-
странство теряется. Данное значение отображает общую сумму утраченного в та-
ких случаях пространства (в байтах).
• Linkdata. Когда используется динамический формат таблиц, фрагменты записи
объединяются посредством указателей (от 4 до 7 байт каждый). Linkdata отобра-
жает суммарный объем памяти, используемый такими указателями.
В случае сжатия таблицы с помощью myisampack опция myisamchk -d будет выво-
дить дополнительную информацию о каждом столбце таблицы. Пример информации
подобного рода и описание того, что она означает, можно найти в разделе 7.2.
340 Глава 4. Администрирование баз данных

4.7. Локализация MySQL и интернациональное


применение
4.7.1. Набор символов для представления данных
и сортировки
По умолчанию MySQL использует набор символов ISO-8859-1 (Latin 1) с сортировкой
в соответствии со шведскими/финскими правилами. Такой набор подходит для приме-
нения в США и большей части стран Западной Европы.
Все бинарные дистрибутивы MySQL компилируются с —with-extra-charsets=
complex. При этом во все стандартные программы добавляется код, который позволяет
им работать с набором символов l a t i n l и многобайтными наборами символов в MySQL.
Остальные наборы символов по необходимости загружаются из специального файла
определений.
Набор символов определяет, какие символы разрешается использовать в именах, а
также то, каким образом будут сортироваться строки во время применения конструкций
ORDER BY И GROUP BY оператора SELECT.
С помощью опции --default-character-set можно изменять набор символов во
время запуска сервера. Доступные наборы символов можно найти через опции
configure: —with-charset=na6op и -with-extra-charsets=cnncofc-Ha6opoB | complex
I a l l I none или в конфигурационных файлах наборов символов, перечисленных в
КАТАЛ0Г_0БЩЕГ0_ИСП0ЛЬ30ВАНИЯ/charsets/Index. См. раздел 2.3.2.
Начиная с версии MySQL 4.1.1, при запуске сервера можно также изменить и тип со-
поставления в наборе символов с помощью опции —default-collation. Однако этот
тип сопоставления должен быть допустимым для набора символов по умолчанию. (Ис-
пользуйте оператор SHOW COLLATION для определения доступных типов сопоставления
для каждого набора.) См. раздел 2.3.2.
Если изменить набор символов во время работы MySQL, это может привести и к из-
менению порядка сортировки. Поэтому необходимо запустить myisamchk -r -q —set-
character-set=Ha6op на всех таблицах, иначе не исключено некорректное упорядочива-
ние индексов.
При подключении клиента к серверу MySQL сервер указывает клиенту, какой набор
символов по умолчанию используется. На время данного соединения клиент переключа-
ется на этот набор.
Во время отмены управляющих символов в строках для SQL-запроса следует
использовать функцию mysql_real_escape_string(). Она идентична старой функции
mysql_escape_string(), но только в качестве первого параметра в ней выступает иден-
тификатор соединения MySQL, так что при отмене управляющих символов учитывается
и соответствующий набор символов.
Во время компиляции клиента, когда были указаны другие пути, отличные от путей к
каталогам, в которые устанавливался сервер, и когда пользователь, проводивший конфи-
гурацию MySQL, не включил все наборы символов в двоичный файл MySQL, обяза-
тельно следует сообщить клиенту, где искать дополнительные наборы символов, кото-
рые могут ему понадобиться, если сервер работает с отличным от набора клиента набо-
ром символов.
4.7. Локализация MySQL и интернациональное применение 341

Это можно сделать с помощью опции — character-sets-dir, указав в ней путь к ка-
талогу, в котором хранятся динамические наборы символов MySQL. Например, добавьте
в файл опций следующую строку:
[client]
character-sets-dir=/usr/local/mysql/share/mysql/charsets
Можно также заставить клиента использовать какой-нибудь определенный набор
символов следующим образом:
[client]
default-character-set=Ha6op
Однако обычно необходимости в этом нет.

4.7.1.1. Использование набора символов немецкого языка


Чтобы сортировка происходила в соответствии с символами немецкого алфавита,
следует запустить mysqld с опцией —default-characterset=latinl_de. Это влияет на
поведение сервера следующим образом:
• Во время сортировки и сравнения строк, перед тем как непосредственно выпол-
нить сравнение, происходит следующее преобразование символов:
а -> ае
б -> ое
и -> ие
В -> ss
• Все символы с ударением преобразуются в свои аналоги без ударения верхнего
регистра. Абсолютно все буквы преобразуются в верхний регистр.
• При сравнении строк с помощью LIKE преобразование символов из одного в два
не происходит. Все буквы преобразуются в верхний регистр. Ударения удаляются
со всех букв, кроме U, и, 0, б, А и а.

4.7.2. Установка языка сообщений об ошибках


По умолчанию mysqld выдает сообщения об ошибках на английском языке, но они
также могут отображаться и на одном из следующих языков: чешском, датском, гол-
ландском, эстонском, французском, немецком, греческом, венгерском, итальянском,
японском, корейском, норвежском, новонорвежском, польском, португальском, румын-
ском, русском, словацком, испанском и шведском.
Чтобы задать определенный язык для сообщений об ошибках во время запуска
mysqld, воспользуйтесь опцией —language или -L. В качестве значения этой опции
можно указать как название языка, так и полный путь к файлу сообщений об ошибках,
например:
shell> mysqld —language=swedish
или:
shell> mysqld —language=/usr/local/share/swedish
Название языка необходимо вводить в нижнем регистре.
Файлы языков находятся (по умолчанию) в папке share/ЯЗЫК базового каталога
MySQL.
342 Глава 4. Администрирование баз данных

Чтобы изменить файл сообщений об ошибках, необходимо отредактировать файл


errmsg. txt, а затем для создания файла errmsg. sys выполнить следующую команду:
shell> comp_err errmsg.txt errmsg.sys
При обновлении версии MySQL не забудьте повторно внести эти же изменения в но-
вый файл errmsg.txt.

4.7.3. Добавление нового набора символов


В данном разделе описываете* процедура по добавлению в MySQL другого набора
символов. Представленные ниже действия применимы, только если установлен исход-
ный дистрибутив MySQL.
Чтобы выбрать подходящий способ, прежде всего, потребуется определить, добав-
ляемый набор символов является простым или сложным:
• Набор символов, при работе с которым не нужны ни специальные операции по
упорядочиванию строк для сортировки, ни поддержка многобайтных символов,
является простым.
• Набор символов, при работе с которым такие возможности (хотя бы одна из них)
необходимы, является сложным.
Например, наборы символов l a t i n l и danish - простые, в то время как big5 и
czech - сложные.
В следующих примерах название набора символов представлено как MYSET.
Чтобы добавить простой набор, необходимо выполнить перечисленные ниже
действия.
1. Добавьте MYSET в конец файла sql/share/charsets/Index и назначьте для него
уникальный номер.
2. Создайте файл sql/share/charsets/MYSET.conf. (В качестве основы для данного
файла можно использовать копию sql/share/charsets/latinl. conf.)
Синтаксис для создания этого файла крайне прост:
• Комментарии начинаются с символа ' # ' и вводятся до конца строки.
• Слова отделяются друг от друга любым количеством пробелов.
• При определении набора символов каждое слово должно быть представлено в
виде шестнадцатеричного числа.
• Массив ctype - это первые 257 слов. Затем идут массивы to_lower[],
to__upper [ ] и sort_order [ ], которые занимают по 256 слов каждый.
См. раздел 4.7.4.
3. Добавьте название набора символов в списки CHARSETS_AVAILABLE и
COMPILED_CHARSETS файла conf igure. in.
4. Повторно сконфигурируйте, скомпилируйте и протестируйте систему.
Для добавления сложного набора символов потребуется сделать следующее:
1. Создайте файл strings/ctype-MySET. с в исходном дистрибутиве MySQL.
2. Добавьте MYSET в конец файла sql/share/charsets/Index и назначьте для него
уникальный номер.
4.7. Локализация MySQL и интернациональное применение 343

3. Просмотрите один из существующих файлов ctype-*.c (например, strings/


ctype-big5. с) с целью выяснения, что же необходимо определить. Обратите вни-
мание на то, что имена массивов в файле должны выглядеть примерно следую-
щим образом: ctype_MYS£T, t o_l о we r J4YSET и так далее. Они соответствуют име-
нам массивов для простого набора символов. См. раздел 4.7.4.
4. Где-то в начале файла вставьте комментарий, подобный приведенному ниже:
/*
* Данный комментарий анализируется программой configure для
* создания файлов типа ctype.c, поэтому не изменяйте его,
* не будучи уверенными в том, что делаете.

* .configure, number_MYSET=MYNUMBER
* .configure. strxfrm_multiply_Mir5ET=N
* .configure. mbmaxlen_MYSET=N
*/
Программа configure использует данный комментарий для автоматического
включения набора символов в библиотеку MySQL.
Строки strxfrmjnultiply и mbmaxlen объясняются ниже. Вводить их нужно толь-
ко при необходимости в наличии функций по упорядочиванию строк или функ-
ций поддержки многобайтных наборов символов соответственно.
5. Затем потребуется создать некоторые из следующих функций:
• my_strncoll_MYS£T()
• my_strcoll_MYS£r()
• my_strxfim_MYSET()
• my_like_range_MYS£T()
См. раздел 4.7.5.
6. Добавьте название набора символов в списки CHARSETS_AVAILABLE и
COMPILED_CHARSETS файла configure.in.
7. Повторно сконфигурируйте, скомпилируйте и протестируйте систему.
8. В файле sql/share/charsets/README содержатся дополнительные инструкции.
При желании, чтобы тот или иной набор символов был включен в дистрибутив
MySQL, можно отправить исправление с ним в список рассылки MySQL internals. См.
раздел 1.7.1.1.

4.7.4. Массивы определения символов


Массивы to_lower [ ] и to_upper [ ] являются простыми и содержат символы верхнего
и нижнего регистров, соответствующие каждому символу из того или иного набора, на-
пример:
to_lower [' А1 ] должен содержать ' а'
to_upper [' а' ] должен содержать ' А'
s o r t o r d e r [ ] представляет собой карту, указывающую, каким образом символы
должны упорядочиваться при их сортировке и сравнении. Достаточно часто (но не для
всех наборов символов) значение sort_order[] эквивалентно значению to_upper[], то
есть в таком случае регистр во время сортировки не учитывается. MySQL выполняет
344 Глава 4. Администрирование баз данных

сортировку символов, основываясь на значениях элементов s o r t o r d e r [ ]. Правила сор-


тировки более подробно рассматриваются в описании функции по упорядочиванию
строк в разделе 4.7.5.
с type [ ] - массив битовых значений, где на каждый символ приходится один эле-
мент. (Обратите внимание, что to_lower[], to_upper[] и sort_order[] индексируются
по значению символа, a ctype[] - по значению символа плюс 1. Это давно принятые
условные обозначения, позволяющие работать с признаком конца файла EOF).
В файле mctype .h можно найти следующие определения битовых масок:
#define U 01 /* Верхний регистр */
#define L 02 /* Нижний регистр */
#define N 04 /* Цифра */
#define _S 010 /* Пробельный символ */
Idefine _P 020 /* Знак пунктуации */
#define С 040 /* Управляющий символ */
#define в 0100 /* Пробел */
#define X 0200 /* Шестнадцатеричная цифра */
Запись с type [ ] для каждого символа должна объединять в себе все подходящие зна-
чения битовых масок, которые его описывают. Например, 'А' является символом верх-
него регистра, а также шестнадцатеричной цифрой (_х), поэтому ctype['A'+l] должна
содержать следующее значение:
_U + _Х = 01 + 0200 = 0201

4.7.5. Поддержка функций по упорядочиванию строк


Если правила сортировки для используемого языка слишком сложны, чтобы обраба-
тываться с помощью sort_order [ ], понадобятся функции по упорядочиванию строк.
На настоящий момент лучшей документацией по этому вопросу являются уже вне-
дренные наборы символов. Для примера см. наборы big5, czech, gbk, s j i s и tisl60.
В специальном комментарии, который размещается в начале файла, необходимо ука-
зать значение strxfrm_multiply _MYSET=N. Для N выбирается значение, соответствующее
максимуму, который могут достигать строки во время выполнения my_strxfrm_MYSET
(это должно быть положительное целое число).

4.7.6. Поддержка многобайтных символов


Если есть необходимость обеспечить поддержку для нового набора символов, который
включает многобайтные символы, потребуется использование специальных функций.
На настоящий момент лучшей документацией по этому вопросу являются уже вне-
дренные наборы символов. Для примера см. наборы символов euc_kr, gb2312, gbk, sjis
и u j is. Эти наборы находятся в файлах ctype-' набор'. с каталога strings.
В специальном комментарии, который размещается в начале исходного файла, необ-
ходимо указать значение mbmaxlen_MYSET=N. Для N выбирается значение, соответствую-
щее размеру (в байтах) самого большого символа в наборе.

4.7.7. Проблемы с наборами символов


При попытке использовать набор символов, который не компилировался в вашу биб-
лиотеку, можно столкнуться со следующими проблемами:
4.8. Журнальные файлы MySQL 345

• В используемой программе указан неправильный путь к каталогу, в котором хра-


нятся наборы символов (По умолчанию это каталог /usr/local/mysql/share/
mysql/charsets). Исправить такую ошибку можно, указав опцию —character-
s e t s - d i r при запуске данной программы.
• Необходимый набор символов является многобайтным набором, динамическая
загрузка которого невозможна. В таком случае потребуется выполнить повторную
компиляцию программы, включив поддержку данного набора.
• Необходимый набор символов является динамическим набором, но конфигураци-
онный файл для него отсутствует. В таком случае потребуется установить такой
файл для данного набора символов из нового дистрибутива MySQL.
• Если в имеющемся индексном файле не содержится имя для данного набора сим-
волов, программа выдаст следующее сообщение об ошибке:
ERROR 1105: File '/usr/local/share/mysql/charsets/?.conf not found
(Errcode: 2)
В таком случае потребуется либо установить новый файл Index, либо вручную
добавить в имеющийся файл название любого из недостающих наборов символов.
Для таблиц My ISAM проверить название и номер используемого в данной таблице на-
бора символов можно с помощью myisamchk -dvv имя_таблицы.

4.8. Журнальные файлы MySQL


MySQL поддерживает несколько разных журнальных файлов, которые могут помочь
узнать, что происходит внутри mysqld (табл. 4.9):

Таблица 4.9. Журнальные файлы MySQL

Журнальный файл Тип заносимой в файл информации


Журнал ошибок Регистрирует все ошибки, происходящие во время запус-
ка, работы или остановки сервера.
Журнал таблиц ISAM Регистрирует все вносимые в таблицы ISAM изменения.
Используется только для отладки кода isam.
Журнал запросов Регистрирует все установленные клиентом соединения и
выполненные операторы.
Журнал регистрации обновлений Регистрирует операторы, которые приводят к изменению
данных. Этот журнал устарел.
Бинарный журнал регистрации Регистрирует все операторы, которые приводят к изме-
нению данных. Также используется при репликации.
Журнал медленных запросов Регистрирует все запросы, выполнение которых заняло
больше, чем указано в long_query_time, секунд, или
запросы, которые не использовали индексов.

По умолчанию все журналы создаются в каталоге данных mysqld. Заставить mysqld


закрыть и открыть журнальные файлы заново (а в некоторых случаях - переключится на
новый журнал) можно с помощью оператора FLUSH LOGS или команд mysqladmin
f l u s h - l o g s и mysqladmin r e f r e s h .
346 Глава 4. Администрирование баз данных

Если используются предлагаемые MySQL возможности репликации, тогда подчи-


ненным сервером также будут поддерживаться и дополнительные журнальные файлы,
называемые журналами ретрансляции. Такие журналы более подробно рассматриваются
в главе 5.

4.8.1. Журнал ошибок


Файл журнала ошибок содержит информацию о том, когда запускался и останавли-
вался сервер, а также любые ошибки, возникшие во время его работы.
Если произойдет неожиданное отключение сервера и mysqld_saf e понадобится пере-
запустить его, то mysqld_safe внесет в журнал ошибок соответствующую запись. Когда
mysqld сталкивается с таблицей, которая нуждается в автоматической проверке или ис-
правлении, сообщение об этом будет также занесено в журнал ошибок.
В некоторых операционных системах журнал ошибок будет еще содержать и данные
трассировки стека, если произойдет аварийное отключения сервера. Такие данные могут
быть использованы для определения, где именно произошел сбой.
Начиная с версии MySQL 4.0.10, с помощью опции —log-error [=имя_файла] можно
задавать каталог, в котором mysqld должен хранить файл журнала ошибок. Если значе-
ние имя_файла не указано, mysqld использует имя имя_хоста. err и заносит этот файл в
каталог данных. (В версиях ниже MySQL 4.0.10 для Windows имя журнала ошибок соот-
ветствует mysql.err.) При применении оператора FLUSH LOGS файл журнала ошибок бу-
дет переименован и сохранен с префиксом -old, a mysqld создаст новый пустой жур-
нальный файл.
В более старых версиях MySQL, используемых в системах Unix, для работы с журна-
лом ошибок применялась опция mysqld_safe, которая выполняла перенаправление фай-
ла ошибок в имя_хоста.еп. Изменить такое имя файла можно, задав для mysqld_safe
опцию —егг1од=имя_файла.
Если не указывать —log-error или (в Windows) использовать опцию —console,
ошибки будут заноситься в stderr (обычно это ваш терминал).
В Windows ошибки всегда записываются в файл .err, если не была задана опция
—console.

4.8.2. Общий журнал запросов


При желании знать обо всем, что происходит внутри mysqld, следует запускать
сервер с опцией —1 од[=имя_файла] или -1 [имя_файла]. (Если не указать значение
имя_файла, будет по умолчанию использоваться имя имя_хоста. log). В таком случае все
устанавливаемые соединения и выполняемые операторы будут регистрироваться в жур-
нале запросов. Такой журнал может очень пригодиться, если есть подозрение о наличии
у клиента ошибки и желании точно узнать, какие именно данные клиент отослал на
mysqld.
Более старые версии сценария mysql.server (начиная с MySQL 3.23.4 и до MySQL
3.23.8) передают safe_mysqld опцию —log, чтобы активизировать общий журнал запро-
сов. Если необходима большая степень производительности при внедрении MySQL в
производственную среду, можно удалить опцию —log из сценария mysql.server или
заменить ее опцией --log-bin. См. раздел 4.8.4.
mysqld записывает операторы в журнал запросов в том порядке, котором он их полу-
чает. Такой порядок может отличаться от порядка, в котором эти операторы выполняют-
4.8. Журнальные файлы MySQL 347

ся. Этим журнал запросов и отличается от бинарного журнала регистрации и журнала


обновлений, которые заполняются после того, как обработан запрос, но перед тем, как
будет отменена любая из блокировок.
Перезапуск сервера и очистка журнала не приводят к созданию нового файла для
общего журнала запросов (хотя команда FLUSH LOG закрывает и открывает журнал сно-
ва). В Unix можно переименовать файл или создать новый, используя следующие ко-
манды:
shell> mv имя__хоста.log имя^хоста-old.log
shell> mysqladmin flush-logs
shell> cp имя_хоста-old.log каталог-резервных-копий
shell> rm имя_хоста-old.log
В Windows переименовать файл журнала, пока он открыт сервером, нельзя. Сначала
следует остановить сервер, присвоить журналу новое имя, а затем перезапустить сервер
для создания нового журнального файла.

4.8.3. Журнал регистрации обновлений


| На заметку!
I I Журнал регистрации обновлений устарел и был заменен бинарным журналом регистрации. См.
|; раздел 4.8.4. Бинарный журнал обеспечивает выполнение всех тех же операций (и даже боль-
{I ше), что и журнал обновлений. Журнал обновлений недоступен, начиная с версии MySQL 5.O.O.

При запуске с опцией —log-update [=имя_файла] сервер mysqld создает журнальный


файл, в котором будут содержаться все SQL-операторы, изменяющие данные. Если зна-
чение имя_файла не указано, для него по умолчанию будет использоваться имя хоста.
Если значение имя^файла задано, но в нем не указан начальный путь к файлу, журнал
будет занесен в каталог данных. Если имя_файла не имеет расширения, mysqld создает
журнальные файлы с именами типа имя_файла.###, где ### представляет собой номер,
увеличивающийся каждый раз при запуске сервера или выполнении команд по очистке
журналов (FLUSH LOGS, mysqladmin flush-logs и mysqladmin refresh).
I На заметку!
Щ Чтобы такая схема присвоения имен работала, не следует создавать свои собственные файлы с
Ш именами, совпадающими с теми, которые могут использоваться для списка журнальных файлов.

Процесс регистрации обновлений носит интеллектуальный характер, потому что в


журнал заносятся только операторы, которые действительно обновляют данные. Таким
образом, операторы UPDATE или DELETE, конструкция WHERE которых не находит подхо-
дящих строк, в журнале не регистрируются. Также пропускаются даже те операторы
UPDATE, которые присваивают столбцу уже имеющееся у него значение.
Данные регистрируются в журнале обновлений сразу же после завершения обработ-
ки того или иного запроса, но прежде чем будет снята любая блокировка или зафиксиро-
вана любая транзакция. Это гарантирует занесение операторов в журнал только в поряд-
ке их выполнения.
При желании обновить базу данных через файлы журнала обновлений можно
сделать следующее (предполагается, что имена журналов обновлений имеют вид
имя_файла . # # # ) :
shell> Is - I - t -г имя_файла.[0-9]* | xargs cat | mysql
Is используется для сортировки имен журнальных файлов в правильном порядке.
348 Глава 4. Администрирование баз данных

Это может пригодиться, если придется после аварии вернуться к резервной копии
файлов, а затем повторно применить обновления, которые были внесены между датой
создания резервной копии и датой аварии.

4.8.4. Бинарный журнал регистрации


Бинарный журнал регистрации заменил собой старый журнал регистрации обновле-
ний, который стал недоступным, начиная с версии MySQL 5.O. Вся информация журна-
ла обновлений сохраняется в бинарном журнале в более эффективном формате и более
безопасным способом.
В бинарный журнал, подобно журналу обновлений, заносятся только операторы, ко-
торые действительно изменяют данные. Таким образом, операторы UPDATE или DELETE,
конструкция WHERE которых не находит подходящих строк, в журнале не регистрируют-
ся. Также пропускаются даже те операторы UPDATE, которые присваивают столбцу уже
имеющееся у него значение.
Бинарный журнал содержит информацию и о том, сколько времени заняло выполне-
ние каждого оператора, посредством которого были внесены изменения в базу данных.
Операторы, не изменяющие никаких данных, в таком журнале не регистрируются. Если
есть необходимость в регистрации абсолютно всех операторов (например, чтобы была
возможность определить запрос, обработка которого оказалась проблематичной), в этих
целях использоваться должен общих журнал запросов. См. раздел 4.8.2.
Основное предназначение бинарного журнала - это предоставить возможность обно-
вить базу данных во время операции восстановления настолько подробно, насколько это
возможно, поскольку именно в бинарном журнале будут содержаться все обновления,
произошедшие после того, как была сделана резервная копия всей системы.
Бинарный журнал также используется на главных серверах в качестве списка опера-
торов, которые подлежат отправке на подчиненные серверы. См. главу 5.
Активизация бинарного журнала регистрации снижает производительность сервера
на 1%. Однако предоставляемые таким журналом преимущества во время проведения
операций по восстановлению или настройки репликации, в целом значительно переве-
шивают этот маленький недостаток.
При запуске с опцией --log-bin [=имя_файла]сервер mysqld создает журнальный
файл, в котором будут сохраняться все SQL-команды, обновляющие данные. Если зна-
чение имя_файла не указано, для него по умолчанию будет использоваться имя хоста с
суффиксом -bin на конце. Если значение имя_файла задано, но пути оно не содержит,
файл будет занесен в каталог данных.
Если в имени журнального файла указать расширение (например, —log-bin=
имя_файла. расширение), оно будет без предупреждения удалено и проигнорировано.
mysqld присоединяет в конец имени бинарного журнала расширение в виде числа, а
именно номера. Этот номер увеличивается каждый раз при перезапуске сервера или
выполнении команд по очистке журналов (FLUSH LOGS, mysqladmin flush-logs и
mysqladmin refresh). Новый бинарный журнал регистрации создается автоматически,
когда размер текущего журнала достигает максимума, заданного в max__binlog_size.
При использовании больших транзакций размер бинарного журнала может дости-
гать и больших, чем указано в m a x b i n l o g s i z e размеров: каждая такая транзакция
регистрируется в журнале целиком и никогда не распределяется между несколькими
журналами.
4.8. Журнальные файлы MySQL 349

Чтобы получить возможность знать, какие файлы каких бинарных журналов приме-
нялись, mysqld также создает и индексный файл, в котором содержатся имена всех ис-
пользуемых файлов бинарного журнала. По умолчанию ему присваивается имя, такое
же, как у файла бинарного журнала, но с расширением ' .index 1 . Изменять имя индекс-
ного файла бинарного журнала можно с помощью опции —log-bin-index= [имя_файла].
Во избежание путаницы редактировать этот файл вручную во время работы mysqld нельзя.
Для удаления всех файлов бинарных журналов используется оператор RESET MASTER,
а для удаления лишь некоторых из них - PURGE MASTER LOGS.
Чтобы контролировать заносимые в бинарный журнал данные, можно применять
следующие опции (также следует ознакомиться с пояснениями, идущими после данного
списка):
• —binlog-do-6Ъ=имя_базы_данных. Указывает главному серверу заносить обнов-
ления в бинарный журнал, если текущей базой данных (то есть базой данных, вы-
бранной с помощью USE) является имя_базы_данных. Все остальные, не упомяну-
тые явно, базы данных игнорируются. При использовании этой опции необходи-
мо проверить, чтобы обновления выполнялись только в текущей базе данных.
Ниже приводится пример того, что не работает так, как ожидается. В случае, ко-
гда сервер был запущен с опцией binlog-do-db=sales и выполняется оператор
USE prices; UPDATE sales.January SET amount=amount+1000;
в бинарный журнал этот оператор занесен не будет.
• —Ып1од-1дпоте-6Ь=имя_базы_данных. Указывает главному серверу не сохранять
обновления в бинарном журнале, если текущей базой данных (то есть базой дан-
ных, выбранной через USE) является имя_базы_данных. При использовании этой
опции необходимо проверить, чтобы обновления выполнялись только в текущей
базе данных.
Ниже приводится пример того, что не работает так, как ожидается. В случае, когда
сервер был запущен с опцией binlog-ignore-db=sales и выполняется оператор
USE prices; UPDATE sales.January SET amount=amount+1000;
этот оператор будет занесен в бинарный журнал.
Чтобы регистрировать или игнорировать обновления сразу нескольких баз данных, за-
дайте соответствующую опцию необходимое число раз, по одному для каждой базы данных.
Правила, по которым обновления будут регистрироваться в бинарном журнале или
игнорироваться, анализируются системой в следующем порядке:
1. Установлены ли правила с помощью —Ь1п1од-йо^Ь=имя_базь/_даняых или

• Если нет, записать оператор в бинарный журнал и завершить работу.


• Если да, перейти к следующему шагу.
2. Определенные правила (—binlog-do-db= имя_базы_данных или —binlog-ignore-
6Ъ=имя_базы_данных) установлены. Имеется ли текущая база данных (была ли ка-
кая-нибудь база данных выбрана при помощи USE?)?
• Если нет, не записывать оператор в бинарный журнал и завершить работу.
• Если да, перейти к следующему шагу.
350 Глава 4. Администрирование баз данных

3. Текущая база данных выбрана. Установлены ли какие-нибудь правила в binlog-do-db?


• Если да, соответствует ли текущая база данных правилам, указанным в
binlog-do-db?
Если да, записать оператор в бинарный журнал и завершить работу.
Если нет, не записывать оператор в бинарный журнал и завершить работу.
• Если нет, перейти к следующему шагу.
4. Определенные правила в binlog-ignore-db установлены. Соответствует ли теку-
щая база данных любому, из указанных правил?
• Если да, не записывать оператор в бинарный журнал и завершить работу.
• Если нет, записать запрос и завершить работу.
Например, подчиненный сервер, запущенный с опцией binlog-do-db=sales, не будет
заносить в бинарный журнал операторы, в которых указано имя текущей базы данных,
отличное от sales (другими словами, иногда binlog-do-db означает "игнорировать дру-
гие базы данных").
При использовании репликации не следует удалять старые файлы бинарных журна-
лов до тех пор, пока не появится полная уверенность в том, что подчиненному серверу
они больше не понадобятся. Единственный способ сделать это - выполнять команду
mysqladmin flush-logs раз в день, после чего удалять любые журналы, созданные более
трех дней назад. Удалять их можно вручную, но предпочтительнее - с помощью опера-
тора PURGE MASTER LOGS, который плюс к этому еще и безопасным образом обновит ин-
дексный файл бинарного журнала (и в котором, начиная с версии MySQL 4.1, в качестве
аргумента можно указывать и дату).
Клиент с привилегией SUPER имеет возможность отключать регистрацию своих опе-
раторов в бинарном журнале, используя SET SQL__LOG_BIN=0.
Для работы с файлами бинарных журналов можно использовать утилиту
mysqlbinlog. Она полезна при желании повторно обработать операторы в журнале. На-
пример, обновить сервер MySQL с помощью бинарного журнала можно следующим
образом:
shell> mysqlbinlog журнальный-файл | mysql -h имя^сервера
Более подробная информация об утилите mysqlbinlog и том, как ее использовать, на-
ходится в разделе 7.5.
Если применяются транзакции, для создания резервных копий вместо старого журна-
ла обновлений следует использовать бинарный журнал регистрации MySQL.
Данные регистрируются в бинарном журнале сразу же после завершения обработки
того или иного запроса, но прежде чем будет снята любая блокировка или зафиксирова-
на любая транзакция. Это гарантирует, что журнал будет заполняться в порядке выпол-
нения операторов.
Обновления нетранзакционных таблиц заносятся в бинарный журнал незамедлитель-
но после их выполнения. Что касается таблиц BDB и InnoDB, все обновления (вносимые с
помощью UPDATE, DELETE или INSERT и изменяющие таблицу) помещаются в кэш до тех
пор, пока сервером не будет получен оператор COMMIT. В этот момент, до того как будет
выполнен COMMIT, mysqld записывает всю транзакцию целиком в бинарный журнал. При
запуске потока, который будет обрабатывать транзакцию, для буферизации запросов
выделяется буфер размером binlog_cache_size. Если оператор превышает данный раз-
4.8. Журнальные файлы MySQL 351

мер, поток открывает временный файл для сохранения транзакции. После закрытия по-
тока временный файл будет удален.
Опцию max__binlog_cache_size (которой по умолчанию присваивается значение
4 Гбайт) можно использовать для ограничения общего объема памяти, выделяемого для
кэширования транзакций с множественными операторами. При превышении указывае-
мого в max_binlog_cache_size значения, выполнение транзакции будет прервано с осу-
ществлением отката.
Если используется журнал обновлений или бинарный журнал, то, когда применяется
оператор CREATE.. .SELECT или INSERT.. .SELECT, параллельные операции вставок будут
преобразовываться в стандартные. Это необходимо для того, чтобы обеспечить возмож-
ность воссоздания точной копии таблиц посредством применения журнала вместе с ре-
зервной копией.
Форматы бинарного журнала в версиях 3.23, 4.0 и 5.0.0 разные. Изменения формата
требовались для улучшения возможностей репликации. В версиях 4.0 и 4.1 формат би-
нарного журнала совпадает. См. раздел 5.5.

48.5. Журнал медленных запросов


При запуске с опцией —log-slow-queries[=имя_файла] сервер mysqld создает жур-
нальный файл, в который будут записываться все SQL-операторы, выполнение которых
заняло больше, чем указано в longquerytime секунд. Время на начальную блокировку
таблиц во времени выполнения запросов не учитывается.
Если значение имя_файла не указано, по умолчанию в качестве имени файла присваи-
вается имя хоста с суффиксом -slow.log. Если имя файла указано, но не задан путь к
нему, файл размещается в каталоге данных.
Оператор записывается в журнал медленных запросов только после того, как он был
выполнен, и после того, как сняты все блокировки. Порядок размещения операторов в
журнале может отличаться от порядка, в котором они выполнялись.
Журнал медленных запросов может использоваться с целью выявления запросов, на
выполнение которых ушло слишком много времени, а, значит, требующих оптимизации.
Однако работать с большим журналом медленных запросов становится задачей не из
простых. В таком случае лучше прогнать журнал через команду mysqldumpslow, которая
отобразит список всех встречающихся в журнале запросов.
Если во время регистрации медленных запросов применяется и опция —log-long-
format, запросы, не использующие индексов, будут тоже записываться в журнал. См.
раздел 4.2.1.

4.8.6. Обслуживание журнальных файлов


Сервер MySQL может создавать целый ряд различных журнальных файлов, с помо-
щью которых узнать о том, что происходит в процессе работы системы, особой сложно-
сти не представляет (см. раздел 4.8). Однако следует проводить регулярную чистку та-
ких файлов, чтобы они не занимали слишком много пространства на диске.
При использовании журналов в MySQL, скорее всего, возникнет потребность в пе-
риодическом удалении их старых файлов или в создании их резервной копии, а также
может появиться необходимость заставить MySQL заносить данные в новые файлы. См.
раздел 4.6.1.
В Linux (Red Hat) для этого можно использовать сценарий mysql-log-rotate. Если
MySQL устанавливался из дистрибутива RPM, то этот сценарий должен был установиться
352 Глава 4. Администрирование баз данных

автоматически. Будьте осторожны с данным сценарием, если для репликации применяется


бинарный журнал! (Нельзя удалять бинарные журналы до тех пор, пока не появится пол-
ная уверенность в том, что их содержимое обработано всеми подчиненными серверами.)
На других системах потребуется собственноручно установить небольшой сценарий
для работы с журнальными файлами, запускаться который будет из сгоп.
Заставить сервер начать использовать новые файлы журналов можно с помощью ко-
манды mysqladmin flush-logs или SQL-оператора FLUSH LOGS. В версии MySQL 3.21
следует применять команду mysqladmin refresh.
Команда по очистке журналов выполняет следующее:
• Если используется стандартный журнал (—log) или журнал медленных запросов
(—log-slow-queries), журнальный файл (mysql.log и имя_хоста-slow.log no
умолчанию) будет закрыт и открыт заново.
• Если используется журнал обновлений (--log-update) или бинарный журнал ре-
гистрации (—log-bin), текущий журнальный файл будет закрыт, а новый жур-
нальный файл с большим порядковым номером - открыт.
Если используется только журнал обновлений, нужно просто переименовать старый
журнальный файл, а затем очистить журналы, прежде чем приступать к резервному ко-
пированию. Например, можно выполнить следующее:
shell> cd каталог-данных-mysql
shell> mv mysql.log mysql.old
shell> mysqladmin flush-logs
После этого подготовьте резервную копию и удалите mysql. old.

49. Запуск нескольких серверов MySQL


на одном и том же компьютере
В некоторых случаях может понадобиться запустить сразу несколько серверов
mysqld на одном и том же компьютере. Например, если нужно протестировать новую
версию MySQL, при этом уже существующая в производственной среде установка
должна остаться нетронутой. Или когда возникает потребность разным пользователям
предоставить доступ к разным серверам mysqld, которыми они будут управлять сами.
(Предположим, вы являетесь поставщиком услуг Internet и хотите обеспечить независи-
мые конфигурации MySQL для разных клиентов.)
При запуске нескольких серверов на одной единственной машине, каждый из серве-
ров должен иметь уникальные значения некоторых рабочих параметров, которые можно
задавать как в командной строке, так и в файлах опций. См. раздел 3.3.
Различным для каждого сервера должны быть, по крайней мере, следующие опции:
• —рогЬ=номер_порта
—port управляет номером порта для TCP/IP-соединений.
• —socket=path
—socket в Unix указывает путь к файлу сокета Unix, а в Windows - имя именованно-
го канала. В Windows обязательно следует указывать точные имена каналов только
для тех серверов, которые поддерживают соединения через именованные каналы.
4.9. Запуск нескольких серверов MySQL на одном и том же компьютере 353

• —shared-memory-base-name=HM#
Эта опция в настоящее время используется только в Windows. Она присваивает имя
разделяемой области памяти, которая используется сервером Windows для разре-
шения клиентам подключаться через эту память. Это новая опция в MySQL 4.1.
• —pid-file=nyTb
Эта опция используется только в Unix. С ее помощью указывается имя файла, в
котором сервер записывает свой идентификатор процесса.
Если представленные ниже опции используются, их значения также должны быть
разными для каждого сервера:
• —log=путь
• —1од-Ып=путь
• —log-update=nyTb
• —1од-еггог=путь
• —log-isam=nyTb
• —bdb-logdir=nyTb
Опции, необходимые для работы с журнальными файлами, описаны в разделе 4.8.6.
Чтобы улучшить производительность системы, можно также по-разному для каждого
сервера задать и представленные ниже опции, что позволит распределять нагрузку меж-
ду несколькими физическими дисками:
• —tmpdir=путь
• —bdb-tmpdiт=путь
Помимо этого рекомендуется, чтобы временные каталоги тоже были разными; так
будет намного легче определять, какой из серверов MySQL создал тот или иной времен-
ный файл.
В общем случае, каждый сервер должен использовать отдельный каталог данных,
путь к которому задается с помощью опции —datadir=путь.
! Внимание!
!;< Обычно ни в коем случае нельзя допускать, чтобы сразу два сервера обновляли данные в одной
Р и той же базе данных! Это может привести к очень неприятным последствиям, если ваша опера-
h ционная система не поддерживает функцию безотказной блокировки доступа! Если (даже не-
смотря на данное предупреждение) для сразу нескольких серверов указан один и тот же каталог
; данных и при этом используется функция регистрации в журналах, обязательно следует с помо-
|;-, щью соответствующих опций задать уникальные для каждого сервера имена журнальных фай-
I лов. В противном случае серверы будут пытаться заносить данные в одни и те же файлы.

Это предупреждение относится и к окружениям, в которых используется сетевая


файловая система (NFS). Разрешить сразу нескольким серверам MySQL доступ к обще-
му каталогу данных через сетевую файловую систему - исключительно плохая идея!
• Основная проблема состоит в том, что в таком случае сетевая файловая система
станет критическим элементом, ограничивающим скорость передачи данных, а
она предназначена вовсе не для этого.
• Еще одна проблема - придется позаботиться об отсутствии конфликтов между
серверами. Обычно в сетевой файловой системе за блокировку доступа отвечает
демон lockd, но в настоящее время платформы, которая бы обеспечивала надеж-
ную на все 100% блокировку в любой ситуации, пока не существует.
354 Глава 4. Администрирование баз данных

Не усложняйте сами себе задачу, то есть о доступе сразу двух (или более) серверов к
одной базе данных через сетевую файловую систему лучше забыть. Подходящим реше-
нием может быть использование одного компьютера с несколькими процессорами и
операционной системы, эффективно управляющей потоками.
При наличии нескольких установок MySQL на разных дисках, обычно для каждого
сервера с помощью опции --basedir=nyTb указывается путь к основному каталогу уста-
новки, в результате чего каждый сервер будет использовать отдельные журнальные и
PID-файлы, а также отдельный каталог данных. (Значения по умолчанию будут зависеть
от каталога данных.) В таком случае дополнительно нужно будет задать только опции
—socket и —port. Например, предположим, что устанавливаются разные версии
MySQL с использованием бинарных дистрибутивов в форме файлов tar. Установлены
они будут в разных местах, поэтому сервер (для каждой из установок) можно будет за-
пускать с помощью команды bin/mysqldsafe из соответствующего каталога данных.
mysqld_safe самостоятельно определит подходящую для передачи mysqld опцию
—basedir; понадобится только указать для mysqld_safe опции —socket и —port. (В
версиях MySQL, предшествующих 4.0, вместо mysqld_safe используйте safejnysqld.)
Как уже рассказывалось в предыдущих разделах, существует также возможность за-
пускать дополнительные серверы путем установки переменных окружения или путем
указания соответствующих опций в командной строке. Однако если использовать не-
скольких серверов одновременно планируется на более постоянной основе, тогда лучше
все значения, которые должны быть уникальными для того или иного сервера, указывать
в файле опций.

4.9.1. Запуск нескольких серверов в Windows


В Windows сразу несколько серверов можно запустить вручную из командной стро-
ки, указав для каждого соответствующие рабочие параметры. В системах Windows NT
существует опция установки и запуска многочисленных серверов как служб Windows.
Основные инструкции по запуску серверов MySQL из командной строки или в качестве
служб перечислены в разделе 2.2.1. Также в этом разделе описывается, как обеспечить,
чтобы все серверы запускались с разными значениями тех опций, которые должны быть
уникальными для каждого сервера, как, например, каталог данных. Такие опции рас-
сматриваются в разделе 4.9.

4.9.1.1. Запуск нескольких серверов в Windows из командной строки


Чтобы запускать сразу несколько серверов вручную из командной строки, можно
указать соответствующие опции в командной строке или в файле опций. Удобнее раз-
мещать опции в файле опций, но обязательно нужно позаботиться о том, чтобы у каждо-
го сервера был свой собственный набор опций. Чтобы добиться такого результата, соз-
дайте отдельный файл опций для каждого сервера и с помощью опции —defaults-file
сообщите серверу имя этого файла при запуске.
Предположим, вы хотите запустить сервер mysqld на порте 3307 с каталогом данных
C:\mydatal и сервер mysqld-max на порте 3308 с каталогом данных C:\mydata2 (прежде
чем делать это, необходимо убедится в том, что оба каталога существуют и содержат
каждый свою копию базы данных mysql, в которой хранятся таблицы привилегий).
Создайте два файла опций. Например, один из них назовите C:\my-optsl.cnf, и вы-
глядеть он должен так:
4.9. Запуск нескольких серверов MySQL на одном и том же компьютере 355

[mysqld]
datadir = C:/mydatal
port = 3307
Второй файл назовите С: \my-opts2. cnf:
[mysqld]
datadir = C:/mydata2
port = 3308
После этого запустите серверы, указав для каждого собственный файл опций:
С:\> C:\mysql\bin\mysqld ~defaults-file=C:\my-optsl.cnf
С:\> С:\mysql\bin\mysqld-max —defaults-file=C:\my-opts2.cnf
В среде NT оба сервера запустятся в приоритетном режиме (до завершения сервера
никаких других приглашений на ввод команд не появится), поэтому указанные выше
команды понадобится выполнять в разных окнах консоли.
Чтобы завершить работу серверов, необходимо подключиться к соответствующему
порту:
С:\> C:\mysql\bin\mysqladmin — port=3307 shutdown
С:\> C:\mysql\bin\mysqladmin —port=3308 shutdown
Серверы, сконфигурированные только что описанным способом, позволяют клиен-
там подключаться через TCP/IP. Если имеющаяся версия Windows поддерживает имено-
ванные каналы и есть желание разрешить установку соединения с сервером через них,
используйте серверы mysqld-nt и mysqld-max-nt, задавая специальные разрешающие
подобные соединения опции, в которых укажите имя соответствующего именованного
канала. Каждый сервер, поддерживающий соединения через именованные каналы, дол-
жен использовать уникальное имя канала. Например, файл C:\my-optsl.cnf может вы-
глядеть следующим образом:
[mysqld]
datadir = C:/mydatal
port = 3307
enable-named-pipe
socket = mypipel
Тогда сервер должен запускаться так, как показано ниже:
С:\> С:\mysql\bin\mysqld-nt —defaults-file=C:\my-optsl.cnf
Таким же способом измените и файл С:\my-opts2.cnf, который используется вторым
сервером.

4.9.1.2. Запуск нескольких серверов в Windows как служб


В системах Windows NT сервер MySQL может запускаться и как одна из служб
Windows. Процедуры установки, управления и удаления службы MySQL описаны в раз-
деле 2.2.1.7.
Начиная с версии MySQL 4.0.2, появилась возможность устанавливать и многочис-
ленные серверы в качестве служб. В таком случае обязательно следует позаботиться о
том, чтобы все серверы помимо уникальных для каждого сервера параметров использо-
вали еще и разные имена служб.
Предлагаемые ниже инструкции предполагают, что вы хотите запустить сервер
mysqld-nt из двух разных версий MySQL, которые установлены в каталоге
356 Глава 4. Администрирование баз данных

С: \mysql-4.0.8 и каталоге С: \mysql-4.0.17 соответственно. (Такой вариант возможен,


когда в производственной среде используется сервер версии 4.0.8, и прежде чем прово-
дить модернизацию до версии 4.0.17, вы хотите эту версию протестировать.)
Следующие принципы верны, когда служба MySQL устанавливается с опцией
— i n s t a l l или —install-manual:
• Если имя службы не указано, сервер использует имя по умолчанию MySQL и счи-
тывает опции из группы [mysqld] стандартных файлов опций.
• Если указать имя службы после опции — i n s t a l l , сервер будет игнорировать
группу опций [mysqld] и вместо этого считывать опции из группы с таким же
именем, как и у службы. Сервер считывает опции из стандартных файлов опций.
• Если после имени службы указать опцию —default-file, сервер будет игнори-
ровать стандартные файлы опций и вместо этого будет считывать опции только из
группы [mysqld] названного файла.
& На заметку!
"X В версиях MySQL, предшествующих 4.0.17, только сервер, при установке которого в качестве
С|; имени службы использовалось имя MySQL (то есть, значение по умолчанию), или сервер, при ус-
%, тановке которого было явно задано имя службы mysqld, будет считывать опции из группы
$ [mysqld] стандартных файлов опций. Начиная с версии MySQL 4.0.17, все серверы, если они
U читают стандартные файлы опций, обращаются к группе [mysqld], даже если они устанавлива-
щ лись с другим именем службы. Это позволяет в группе [mysqld] указывать те опции, которые
|| должны использоваться всеми службами MySQL, а в группе опций, называемой именем опреде-
|jf ленной службы - опции, которые будут использоваться только установленным с таким же име-
$ нем службы сервером.

Исходя из всего вышесказанного, можно сделать вывод о том, что существует не-
сколько способов установки сразу нескольких служб MySQL на одном компьютере.
Приведенное ниже описание этих способов включает и некоторые примеры. Прежде чем
пытаться проверить любой из них, сначала убедитесь, что все существующие службы
MySQL были закрыты и удалены.
• Способ 1. Задавайте опции для всех служб в одном из стандартных файлов опций.
Для этого необходимо для каждого сервера указать отдельное имя службы. Пред-
положим, вы хотите запустить сервер mysqld-nt версии 4.0.8, используя имя
службы mysqldl, и сервер mysqld-nt версии 4.0.17, используя имя службы
mysqld2. В таком случае для сервера 4.0.8 можно указать группу [mysqldl ], а для сер-
вера 4.0.17 - группу [mysqld2 ]. Например, файл С: \my. cnf может выглядеть так:
# Опции для службы mysqldl
[mysqldl]
basedir = C:/mysql-4.0.8
port = 3307
enable-named-pipe
socket = mypipel
# Опции для службы mysqld2
[mysqld2]
basedir = C:/mysql-4.0.17
port = 3308
enable-named-pipe
socket = mypipe2
4.9. Запуск нескольких серверов MySQL на одном и том же компьютере 357

Установите службы, как показано ниже, указывая пути к серверу полностью; это
гарантирует, что Windows будет регистрировать правильные выполняемые про-
граммы для каждой службы:
С:\> C:\mysql-4.0.8\bin\mysqld-nt —install mysqldl
С:\> C:\mysql-4.0.17\bin\mysqld-nt —install mysqld2
Чтобы запустить службы, используйте диспетчер служб или оператор NET START с
соответствующими именами служб:
С:\> NET START mysqldl
С:\> NET START mysqld2
Чтобы завершить работу служб, используйте диспетчер служб или оператор NET
STOP с соответствующими именами служб:
С:\> NET STOP mysqldl
С:\> NET STOP mysqld2
• Способ 2. Задавайте опции для каждого сервера в отдельном файле и, когда уста-
навливаете службы, применяйте —defaults-file, чтобы указать каждому серве-
ру, какой файл он должен использовать. В таком случае все опции следует пере-
числять в группе [mysqld] каждого отдельного файла.
При таком способе, чтобы указать опции для mysqld-nt версии 4.0.8, создайте
файл С: \myoptsl. cnf, который должен выглядеть так:
[mysqld]
basedir = С:/mysql-4.0.8
port = 3307
enable-named-pipe
socket = mypipel
Для сервера mysqld-nt версии 4.0.17 создайте файл C:\my-opts2.cnf, который
должен выглядеть так:
[mysqld]
basedir = С:/mysql-4.О.17
port = 3308
enable-named-pipe
socket = mypipe2
Установите службы следующим образом (вводите каждую команду в одной строке):
С:\> C:\mysql-4.0.8\bin\mysqld-nt —install mysqldl
—defaults-file=C:\my-optsl.cnf
C:\> C:\mysql-4.0.17\bin\mysqld-nt —install mysqld2
—defaults-file=C:\my-opts2.cnf
При установке MySQL в качестве службы, чтобы использовать опцию
--defaults-file, перед ней необходимо указывать имя службы.
После того, как службы MySQL установлены, запустить или остановить их можно
способами, описанными в предыдущем примере.
Чтобы удалить службы MySQL, для каждой из них используйте опцию mysqld
—remove, указывая после —remove имя службы. Если это имя MySQL (то есть имя,
установленное по умолчанию), его можно и не указывать.
358 Глава 4. Администрирование баз данных

4.9.2. Запуск нескольких серверов под Unix


Самый простой способ запустить несколько серверов в Unix - это скомпилировать их
с разными TCP/IP-портами и файлами сокетов Unix, чтобы каждый из них прослушивал
соединения через разные сетевые интерфейсы. Также компиляция с разными для каждой
установки MySQL каталогами данных автоматически приводит к тому, что серверы бу-
дут использовать каждый свои журналы, PID-файлы и каталоги данных.
Предположим, что существующий сервер сконфигурирован со значениями по умол-
чанию для TCP/IP-порта (3306) и файла сокета Unix (/tmp/mysql.sock). Для конфигури-
рования нового сервера с другими рабочими параметрами воспользуйтесь командой
configure, подобной показанной ниже:
shell> ./configure —with-tcp-porЬ=номер_порта \
—with-unix-socket-paЬЬ=имя_файла \
—prefix=/usr/local/mysql-4.0.17
Здесь номер_порта и имя_файла должны отличаться от устанавливаемых по умолча-
нию значений для номера TCP/IP-порта и пути к файлу сокета Unix, а в —prefix должен
указываться каталог установки, не совпадающий с каталогом, в котором расположена
текущая версия MySQL.
При наличии сервера, прослушивающего соединения через определенный порт,
можно выполнить следующую команду, чтобы узнать, какие рабочие параметры исполь-
зует сервер для некоторых важных реконфигурируемых переменных, включая имя ос-
новного каталога и имя файла сокета Unix:
shell> mysqladmin —hosЬ=имя_хоста —рогЬ=номер_порта variables
Отображаемая с помощью этой команды информация позволяет понять, какие значе-
ния опций использовать не нужно при конфигурации дополнительного сервера.
Обратите внимание, что если задать в качестве имени хоста local host, mysqladmin no
умолчанию для соединения будет использовать файл сокета Unix, а не TCP/IP. В MySQL
4.1 можно явно указать протокол, который следует использовать для соединения, с по-
мощью ОПЦИИ --protocol^TCP I SOCKET j PIPE | MEMORY}.
He нужно компилировать новый сервер, чтобы просто запустить его с другими зна-
чениями для файла сокета Unix и номера порта TCP/IP. Данные значения можно задать и
во время выполнения. Один из способов это сделать - использовать опции командной
строки:
shell> mysqld_safe —sockeЬ=имя__файла —рогЬ=номер_порта
Для запуска второго сервера укажите другие значения в опциях —socket и —port и
передайте для mysqld_safe опцию —datadir=nyTb, чтобы сервер использовал другой
каталог данных.
Еще один способ добиться подобных результатов - для установки имени файла соке-
та Unix и номера порта TCP/IP использовать переменные окружения:
shell> MYSQL_UNIX_PORT=/tmp/mysqld-new. sock
shell> MYSQL_TCP_PORT=3307
shell> export MYSQLJJNIXJ>ORT MYSQLJTCPJPORT
shell> mysqlJLnstall^db —user=mysql
shell> mysqld_safe —datadir=/путь/к/каталогу_даиных &
Этот самый быстрый метод, позволяющий запустить второй сервер для целей тести-
рования. Его положительная сторона состоит в том, что настройки переменных окруже-
4.9. Запуск нескольких серверов MySQL на одном и том же компьютере 359

ния будут применяться ко всем клиентским программам, вызываемым из одной и той же


командной оболочки. Таким образом, соединения для таких клиентов будут автоматиче-
ски направляться второму серверу!
В приложении Б представлен список переменных окружения, которые можно ис-
пользовать для работы с mysqld.
Для автоматического запуска сервера специальный сценарий, выполняемый во время
начальной загрузки системы, должен выполнять следующую команду один раз для каж-
дого сервера, в каждой их которых указывается соответствующий путь к файлу опций:
mysqld_safe —defaults-file=nyrb
В каждом файле опций должны содержаться специальные для данного сервера зна-
чения опций.
В Unix еще один способ запустить несколько серверов на одном компьютере преду-
сматривает использование сценария mysqldjnulti. См. раздел 4.1.5.

4.9.3. Использование клиентских программ в окружении


с несколькими серверами
При необходимости подключить клиентскую программу к серверу MySQL, прослу-
шивающему сетевые интерфейсы, отличные от тех, с которыми скомпилирован клиент,
можно воспользоваться одним из следующих методов:
• Запустите клиент с опцией —ho8Ь=имя_хоста —ро г t=HOMep_nopTa, чтобы под-
ключиться через TCP/IP к удаленному серверу, или с опцией — host=127.0.0.1
—рогЬ=номер_порта, чтобы подключиться через TCP/IP к локальному серверу,
или с опцией —host=localhost —sоскеЬ=имя_файла, чтобы подключиться к ло-
кальному серверу через файл сокета Unix либо именованный канал Windows.
• Начиная с версии MySQL 4Л, можно запускать клиент с опцией —protocol=tcp,
чтобы подсоединяться через TCP/IP, или с опцией --protocol=socket, чтобы под-
ключаться через файл сокета Unix, или с опцией — protocol=memory, чтобы под-
соединяться через совместно используемую память. Для TCP/IP-соединений так-
же может понадобиться указывать опции --host и —port. Для других типов со-
единений может потребоваться задать опцию —socket, в которой указывается файл
сокета Unix или именованный канал, или же опцию —shared-memory-base-name, в
которой указывается имя совместно используемой памяти. Соединения через со-
вместно используемую память поддерживаются только в Windows.
• В Unix, прежде чем запускать клиенты, установите переменные окружения
MYSQL_UNIX_PORT и MYSQL_TCP_PORT, в которых укажите файл сокета Unix или но-
мер порта TCP/IP. Если обычно используется какой-то конкретный файл сокета
или номер порта, можно поместить команды, задающие эти переменные окруже-
ния, в файл . login, тогда они будут применяться каждый раз при входе в систему.
См. приложение Б.
• Укажите используемые по умолчанию файл сокета Unix и номер порта TCP/IP в
группе [client] файла опций. Например, это может быть файл опций С: \my.cnf в
Windows или файл .my.cnf домашнего каталога в Unix. См. раздел 3.3.2.
360 Глава 4. Администрирование баз данных

• В программе на С можно задать аргументы файла сокета и номера порта в вызове


функции mysql_real_connect (). Также можно заставить программу считывать
файлы опций, вызвав mysql_options ().
• При использовании модуля Perl DBD::mysql можно считывать опции из файлов
опций MySQL. Например:
$dsn = "DBI:mysql:test;mysql_read_default_group=client;"
. "mysql_read_default_file=/usr/local/raysql/data/my.cnf';
$dbh = DBI->connect($dsn, $user, $password);
Другие интерфейсы программирования для чтения файлов опций могут предла-
гать возможности, подобные описанным выше.

410. Кэш запросов MySQL


Начиная с версии 4.0.1, сервер MySQL предлагает кэш запросов. При использовании
кэш запросов сохраняет текст запроса SELECT вместе с соответствующим результатом,
который был отправлен клиенту. Когда в следующий раз поступает идентичный запрос,
сервер вместо того, чтобы снова анализировать и выполнять его, извлекает уже имею-
щиеся по такому запросу результаты из кэша.
Кэш запросов крайне удобно использовать в среде, где (некоторые) таблицы не изме-
няются слишком часто и количество идентичных запросов велико. Такая ситуация явля-
ется типичной для большинства Web-серверов, генерирующих огромное число динами-
ческих страниц, основанных на содержимом базы данных.
Щ. На заметку!
У: Кэш запросов не возвращает устаревшие данные. При изменении таблиц любые записи в кэше
!/ запросов, имеющие отношение к этим изменениям, удаляются.

£ На заметку!
; Кэш запросов не работает в среде, где сразу несколько серверов mysqld обновляют одни и те
;1 же таблицы.

Ниже представлены некоторые данные по функционированию кэша запросов. Они


были собраны во время работы с контрольным комплектом MySQL в системе Linux
Alpha 2 х 500 МГц с ОЗУ объемом 2 Гбайт и кэшем запросов размером 64 Мбайт.
• Если все выполняемые запросы являются простыми, но при этом отличаются ме-
жду собой настолько, что не могут быть помещены в кэш, непроизводительные
издержки на использование кэша запросов соответствуют 13%. Это можно рас-
сматривать как наихудший возможный вариант. На практике запросы обычно на-
много сложнее, а поэтому и издержки значительно ниже.
• Поиск строки в однострочной таблице происходит на 238% быстрее при наличии
кэша запросов. Этот коэффициент можно рассматривать как близкий к минималь-
ному коэффициент ускорения вычислений, ожидаемый для обработки запроса,
который находится в кэше.
Чтобы отключить кэш запросов при запуске сервера, необходимо для системной пе-
ременной q u e r y c a c h e s i z e установить значение 0. В таком случае не будет никаких
заметных непроизводственных издержек. Полностью исключить использование воз-
можностей кэша запросов на сервере можно, указав во время компиляции MySQL в про-
грамме configure опцию —without-query-cache.
4.10. Кэш запросов MySQL 361

4.10.1. Как работает кэш запросов


В данном разделе описывается, как работает кэш запросов, когда он активизирован, а
в разделе 4.10.3 - как управлять его работой.
Перед синтаксическим анализом запросы сравниваются, поэтому следующие два за-
проса рассматриваются кэшем запросов как разные:
SELECT * FROM имя_таблицы
S e l e c t * from имя_таблицы
Чтобы рассматриваться как идентичные, запросы должны быть абсолютно одинако-
выми (байт в байт). Кроме того, строки запросов, являющиеся идентичными, могут
трактоваться как отличающиеся друг от друга по каким-то другим причинам. Запросы,
использующие разные базы данных, разные версии протоколов или разные наборы сим-
волов по умолчанию считаются неодинаковыми и помещаются в кэш по отдельности.
При возвращении результата запроса из кэша запросов сервер увеличивает значение
переменной состояния Qcache_hits, а не Com_select. См. раздел 4.10.4.
Если таблица изменяется, все помещенные в кэш запросы, которые использовали
данную таблицу, становятся недействительными и удаляются из кэша. (Сюда относятся
и запросы, использующие таблицы MERGE, которые преобразовываются в измененную
таблицу.) Таблица может быть изменена посредством самых разных типов операторов,
т а к и х к а к INSERT, UPDATE, DELETE, TRUNCATE, ALTER TABLE, DROP TABLE ИЛИ DROP DATABASE.
Измененные транзакционные таблицы innoDB становятся недействительными при
выполнении оператора COMMIT.
В версии MySQL 4.0 кэш запросов блокируется во время выполнения транзакций (он
не возвращает результатов). Начиная с версии MySQL 4.1.1, кэш запросов работает и во
время выполнения транзакций при применении таблиц InnoDB (он использует номер
версии таблицы, чтобы определить, является ли ее содержимое по-прежнему текущим).
В версиях MySQL, предшествующих 5.0, запрос, начинающийся с комментария, мо-
жет быть помещен в кэш, но вот выбран оттуда быть не может. В MySQL 5.0 упомяну-
тая проблема устранена.
Кэш работает С запросами типа SELECT SQL_CALC_FOUND_ROWS. . . И SELECT FOUND_ROWS().
FOUND_ROWS () возвращает правильное значение, даже если из кэша был выбран пре-
дыдущий запрос, потому что в кэше также хранится и число найденных строк.
Запрос не может быть помещен в кэш, если он содержит любую из следующих
функций:
BENCHMARK() CONNECTION_ID() CURDATE()
CURRENT_DATE() CURRENT_TIME() CURRENT_TIMESTAMP()
CURT IME () DATABASE () ENCRYPT () (с о д н и м параметром)
FOUND_ROWS() GET_LOCK() LAST_INSERT_ID()
LOAD_FILE() MASTER_POS_WAIT() NOW ()
RANDO RELEASE_LOCK() SYSDATE()
UNIX_TIMESTAMP () ( б е з параметров) USER ()

Запрос также не будет помещаться в кэш при следующих условиях:


• Если он содержит определяемые пользователем функции (UDF).
• Если он содержит переменные пользователя.
• Если он относится к таблицам из системной базы данных mysql.
362 Глава 4. Администрирование баз данных

• Если он представлен в виде:


SELECT . . . IN SHARE MODE
SELECT . . . INTO OUTFILE . . .
SELECT . . . INTO DUMPFILE . . .
SELECT * FROM . . . WHERE столбец_аиЬоincrement IS NULL

Последний из перечисленных запросов не помещается в кэш, поскольку используется


при работе с ODBC для получения значения идентификатора последней вставки.
• Если он использует таблицы TEMPORARY.
• Если он не использует никаких таблиц.
• Если пользователь имеет привилегию на уровне столбцов для любой из исполь-
зуемых таблиц.
• Перед тем как запрос будет выбран из кэша запросов, MySQL проверяет, имеет ли
пользователь привилегию SELECT для любой из задействованных баз данных или
таблиц, и если нет, то кэшированный результат не используется.

4.10.2. Опции SELECT для кэша запросов


Существует две опции, имеющие отношение к кэшу запросов, которые можно зада-
вать в операторе SELECT:
• SQL_CACHE. Результат запроса будет помещен в кэш, если значение системной пе-
ременной query_cache_type равно ON или DEMAND.
• SQL_NO_CACHE. Результат запроса не будет помещен в кэш.
Примеры:
SELECT SQL_CACHE id, name FROM customer;
SELECT SQL_NO_CACHE id, name FROM customer;

4.10.3. Конфигурирование кэша запросов


Системная переменная сервера have_query_cache указывает, доступен ли кэш запросов:
f
mysql> SHOW VARIABLES LIKE 'have_query_cache ;
+ + +
| Variable_name | Value |

I have_query_cache | YES |

Несколько других системных переменных управляют работой кэша запросов. Их


можно задавать в файле опций или в командной строке при запуске mysqld. Все систем-
ные переменные, имеющие отношение к кэшу запросов, начинаются с query_cache_.
Кратко они описываются в разделе 4.2.3, а дополнительная информация по их конфигу-
рации представлена здесь.
Размер кэша запросов устанавливается в системной переменной query_cache_size.
Если указать в ней значение 0, кэш запросов будет отключен. Значение по умолчанию
равно 0, то есть кэш запросов не активизирован.
Если кэш запросов используется, то значение переменной query_cache_size будет
влиять на его работу. Могут быть установлены следующие значения:
4.10. Кэш запросов MySQL 363

• 0 или OFF ("выключено") - запросы не кэшируются и кэшированные результаты


не извлекаются.
• 1 или ON ("включено") - в кэш помещаются все операторы за исключением тех,
которые начинаются с SELECT SQL_NO_CACHE.
• 2 или DEMAND ("по требованию") - в кэш помещаются только те операторы, кото-
рые начинаются с SELECT SQL_CACHE.
Значение GLOBAL переменной query_cache_type определяет поведение кэша запросов
для всех клиентов, подключающихся после того, как внесены изменения. Отдельные
клиенты могут регулировать поведение кэша запросов для своих собственных соедине-
ний, устанавливая значение SESSION в переменной query_cache_type. Например, клиент
может отключить использование кэша запросов для своих собственных запросов сле-
дующим образом:
mysql> SET SESSION query_cache_type = OFF;
Чтобы ограничить максимальный размер помещаемых в кэш результатов отдельных
запросов, установите значение переменной query_cache_limit. Значение по умолчанию
составляет 1 Мбайт.
Результат запроса (данные, которые были отправлены клиенту) сохраняется в кэш
запросов во время извлечения результатов. Поэтому данные обычно не обрабатываются
одной большой порцией. Кэш запросов выделяет блоки для сохранения данных по необ-
ходимости, таким образом, когда один блок заполнен, создается новый. Поскольку опе-
рация по распределению памяти обходится дорого (то есть занимает немалый промежу-
ток времени), кэш запросов выделяет блоки с минимальным размером, указанным в сис-
темной переменной query__cache_min_res_unit. После того, как запрос выполнен,
последний блок с результатами усекается в соответствии с фактическим размером дан-
ных, тем самым высвобождается неиспользуемая память. В зависимости от выполняе-
мых сервером типов запросов, можно варьировать значения query_cache_min_res_unit:
• По умолчанию значение query_cache_min_res_unit составляет 4 Кбайт и должно
подходить в большинстве случаев.
• При большом количестве запросов с маленькими результатами, использование
принятого по умолчанию размера блоков может привести к фрагментации памяти,
поскольку в таком случае количество свободных блоков велико. Фрагментация, в
свою очередь, не исключает удаления (отсечения) запросов из кэша по причине
недостаточного количества доступной памяти. В такой ситуации следует умень-
шить значение query_cache_min_res_unit. Число свободных блоков и запросов,
удаленных в результате описанного отсечения указано в переменных состояния
Qcache_free_blocks и Qcache_lowmem_prunes.
• Если результаты практически всех запросов большие (проверьте значения пере-
менных состояния Qcache_total_blocks и Qcache_queries_cache), повысить про-
изводительность системы можно, увеличив query_cache_min_res_unit. Однако
следите за тем, чтобы оно не оказалось слишком большим (см. предыдущий
пункт).

4.10.4. Состояние кэша запросов и его обслуживание


Проверить наличие кэша запросов в MySQL можно с помощью следующего оператора:
364 Глава 4. Администрирование баз данных

mysql> SHOW VARIABLES LIKE ' h a v e _ q u e r y _ c a c h e ' ;


+ + +
I Variable_name I Value I
+ + +
I have_query_cache I YES |

С помощью оператора FLUSH QUERY CACHE можно выполнить дефрагментацию кэша


запросов для лучшего использования его памяти. Никаких запросов из кэша данный
оператор не удаляет. Оператор RESET QUERY CACHE удаляет все результаты запросов из
кэша запросов. То же самое делает и оператор FLUSH TABLES.
Контролировать эффективность кэша запросов можно с помощью оператора SHOW
STATUS, который позволяет просмотреть переменные состояния кэша:
mysql> SHOW STATUS LIKE l Qcache% ! ;

I Variable_name I Value I
+ + +
I Qcache_free_blocks I 36 |
I Qcache_free_memory I 138488 |
I Qcachejiits I 79570 |
I Qcache_inserts I 27087 |
I Qcache_lowmem_prunes I 3114 |
I Qcache_not_cached I 22989 |
i Qcache_queries_in_cache | 415 |
I Qcache_total_blocks I 912 |
+ + +

Описание каждой из этих переменных дается в разделе 4.2.4. Использование некото-


рых из них рассматривается ниже.
Общее число запросов SELECT равняется:
Com_select
+ Qcache_hits
+ запросы с ошибками, обнаруженные анализатором
Значение Com_select состоит из:
Qcache_inserts
+ Qcache_not_cached
+ запросы с ошибками, обнаруженные во время проверки столбцов/прав
Кэш использует блоки переменной длины, поэтому значения Qcache_total_blocks и
Qcache_free_blocks могут означать фрагментацию памяти кэша запросов. После ис-
пользования оператора FLUSH QUERY CACHE остается только один свободный блок.
Для каждого кэшированного запроса требуется минимум два блока (один для текста
запроса, а другой или другие для результатов запроса). Также для каждой используемой
в запросе таблицы тоже нужен один блок. Однако если два или более запросов исполь-
зуют одну и ту же таблицу, выделяется только один блок.
Данные, предоставляемые переменной состояния Qcache_lowmem_prunes, могут помочь
выбрать подходящее значение для размера кэша запросов. Переменная подсчитывает коли-
чество запросов, удаленных из кэша с целью освобождения памяти для кэширования новых
запросов. При удалении запросов кэш выбирает запросы с наиболее давним использовани-
ем (least recently used - LRU). Информация о настройке кэша содержится в разделе 4.10.3.
5

Репликация в MySQL

В озможности репликации позволяют базе данных на одном сервере MySQL дубли-


роваться на другом, на котором установлен MySQL версии не ниже 3.23.15. В на-
стоящей главе описаны различные средства репликации, предоставляемые MySQL. В
ней представлены основные концепции репликации, объяснено, как настраивать сервер
репликации, и предложено руководство по доступным опциям репликации. Глава также
включает список наиболее часто задаваемых вопросов (с ответами) и советы по устране-
нию неисправностей.
Описание синтаксиса операторов SQL, касающихся репликации, можно найти в кни-
ге MySQL. Справочник по языку.
Мы советуем почаще заглядывать на наш сайт http://www.mysql.com на предмет оз-
накомления с изменениями к настоящей главе. Репликация постоянно развивается, по-
этому руководство часто обновляется.

5.1. Введение в репликацию


MySQL 3.23.15 и выше поддерживает одностороннюю репликацию. Один сервер вы-
ступает ведущим, или главным (master), в то время как один или более серверов - ведо-
мыми, или подчиненными (slave). Главный сервер записывает изменения в свои файлы
бинарных журналов и поддерживает индекс файлов для отслеживания ротации журна-
лов. Эти журналы хранят записи об изменениях данных, которые должны быть разосла-
ны подчиненным серверам. Когда подчиненный сервер подключается к главному, он
информирует его о позиции в журналах, до которой было выполнено последнее удачное
обновление данных. Подчиненный сервер затем захватывает все изменения, которые
накопились с тех пор на главном сервере, блокируется и ожидает извещений от главного
сервера о новых изменениях.
Подчиненный сервер также может быть одновременно и главным, если вы хотите по-
строить цепочку реплицируемых серверов.
Помните, что когда вы используете репликацию, все изменения в таблицах, которые
реплицируются, должны выполняться на главном сервере. В противном случае потребу-
ется предельная внимательность во избежание конфликтов между изменениями, кото-
рые пользователи выполняют в таблицах главного сервера, и изменениями, которые они
могут провести в таблицах подчиненного.
Односторонняя репликация обладает преимуществами в плане устойчивости, скоро-
сти и простоте администрирования:
366 Глава 5. Репликация в MySQL

• Устойчивость растет при установке главного/подчиненного серверов. В случае


возникновения проблем на главном сервере, вы можете переключиться на подчи-
ненный, как на резервный.
• Лучшее время ответа для клиентов может быть достигнуто разделением нагрузки
клиентских процессов между главным и подчиненным серверами. SELECT может
быть отправлен подчиненному серверу, чтобы снизить запросную нагрузку глав-
ного. Операторы, модифицирующие данные, должны по-прежнему направляться
только главному серверу, поэтому главный и подчиненный всегда остаются син-
хронизированными. Стратегия балансирования нагрузки эффективна, если доми-
нируют немодифицирующие запросы, и это нормальный случай.
• Другая выгода применения репликации состоит в том, что вы можете выполнять
резервное копирование данных с подчиненного сервера, не беспокоясь о главном.
Главный сервер продолжает обновлять данные, пока выполняется резервное ко-
пирование. См. раздел 4.6.1.

5.2. Обзор реализации репликации


Репликация MySQL основывается на том, что главный сервер записывает все изме-
нения базы данных (обновления, удаления и так далее) в бинарном журнале. Поэтому,
чтобы использовать репликацию, вы должны включить бинарную регистрацию на глав-
ном сервере (см. раздел 4.8.4).
Каждый подчиненный сервер принимает от главного сохраненные изменения, кото-
рые тот записал в свой бинарный журнал; таким образом, подчиненный сервер может
провести те же изменения в своей копии данных.
Очень важно понимать, что бинарный журнал - это просто запись, начатая от фикси-
рованного момента времени, когда была запущена бинарная регистрация. Любые подчи-
ненные серверы, которые вы устанавливаете, нуждаются в копии данных главного сер-
вера в том виде, в каком они пребывали на момент начала регистрации. Если запустить
подчиненный сервер с базами данных, отличными от тех, что были на главном сервере
при старте регистрации, подчиненный сервер может аварийно завершиться.
Единственный способ скопировать данные главного сервера на подчиненные пред-
полагает применение команды LOAD DATA FROM MASTER. Помните, что LOAD DATA FROM
MASTER доступна, начиная с версии MySQL 4.0.0, и в настоящее время работает, только
если все таблицы принадлежат к типу My ISAM. К тому же этот оператор требует глобаль-
ной блокировки по чтению, поэтому никакие обновления данных на главном сервере
невозможны, пока данные передаются на подчиненный сервер. Когда мы, наконец, реа-
лизуем свободное от блокировок резервное копирование таблиц (в MySQL 5.0), такая
глобальная блокировка будет не нужна.
Из-за этих ограничений мы рекомендуем, чтобы на данный момент вы использовали
LOAD DATA FROM MASTER только в случаях, когда объем данных относительно невелик,
либо допустим длительный простой главного сервера. Так как реальная скорость выпол-
нения LOAD DATA FROM MASTER может варьироваться от системы к системе, хорошим
правилом определения временных затрат будет предположение, что понадобится 1 се-
кунда на 1 Мбайт данных. Это только грубое приближение, но оно близко к реальности,
если и главный и подчиненный серверы - одинаковые машины на базе, скажем, процес-
сора Pentium с частотой 700 МГц, соединенные через сеть 100 Мбит/с.
5.3. Детали реализации процесса репликации 367

После того, как подчиненный сервер получит копию данных главного сервера, он
просто подключается к нему и ожидает обновлений, которые нужно обработать. Ес-
ли главный сервер отключится, либо пропадет связь, он будет повторять периодиче-
ские попытки подключиться снова до тех пор, пока ему это не удастся, и он не про-
должит прослушивать изменения. Интервал повторения попыток управляется опцией
—master-connect-retry. По умолчанию он составляет 60 секунд.
Каждый подчиненный сервер запоминает, на каком этапе он утратил связь. Главный
сервер не имеет понятия о том, сколько подчиненных серверов к нему подключено, и
какие из них хранят актуальную информацию в любой момент времени.

5.3. Детали реализации процесса репликации


Средство репликации MySQL реализовано с использованием трех потоков (один на
главном сервере и два - на подчиненном). После выдачи команды START SLAVE подчи-
ненный сервер создает поток ввода-вывода. Этот поток подключается к главному серве-
ру и запрашивает у него операторы, записанные в его бинарных журналах. Главный сер-
вер создает поток для отправки содержимого бинарного журнала подчиненному серверу.
Этот поток можно идентифицировать как Binlog Dump в выводе команды SHOW
PROCESSLIST на главном сервере. Поток ввода-вывода получает то, что отсылает Binlog
Dump, и просто копирует в локальные файлы каталога данных, называемые трансляцион-
ными журналами (relay logs). Третий поток - это поток SQL, который создает подчинен-
ный сервер для чтения трансляционных журналов и выполнения хранящихся в них об-
новлений.
Из предыдущего описания следует, что создается три потока на каждый подчинен-
ный сервер. На главном сервере, у которого таких подчиненных серверов несколько,
создается один поток для каждого подключенного подчиненного сервера, а каждый из
них, в свою очередь, запускает свой собственный поток ввода-вывода и поток SQL.
В версиях MySQL, предшествующих 4.0.2, в процессе репликации создавались толь-
ко два потока (один - на главном сервере и один - на подчиненном). Потоки, занимаю-
щиеся вводом-выводом и отработкой SQL-операторов, были скомбинированы в один, и
никаких трансляционных журналов не использовалось.
Выгода от использования двух потоков на подчиненном сервере состоит в том, что
чтение операторов и их выполнение разделены на две независимых задачи. Задача чте-
ния операторов не замедляется, если замедлено их выполнение. Например, если подчи-
ненный сервер не запускался долгое время, при старте его поток ввода-вывода быстро
получит все содержимое бинарного журнала от главного сервера, даже если поток обра-
ботки SQL будет отставать, и ему потребуются многие часы для того, чтобы догнать.
Если подчиненный сервер остановится до того, как поток SQL обработает все получен-
ные операторы, по крайней мере, поток ввода-вывода уже получит все, поэтому безо-
пасная копия операторов уже будет локально сохранена в трансляционных журналах
подчиненного сервера для последующего выполнения, когда он будет запущен снова.
Это позволит очистить бинарный журнал главного сервера, поскольку ему больше не
нужно ждать подчиненного сервера, чтобы передать содержимое этого журнала.
Оператор SHOW PROCESSLIST предоставляет информацию о том, какие действия, свя-
занные с репликацией, происходят на главном и подчиненном серверах.
Следующий пример иллюстрирует, как эти три потока отображает SHOW PROCESSLIST.
Представленный формат вывода характерен для SHOW PROCESSLIST в версии MySQL
368 Глава 5. Репликация в MySQL

4.0.15, когда содержимое столбца State изменилось, чтобы быть более информативным,
чем в ранних версиях.
На главном сервере вывод SHOW PROCESSLIST выглядит так:
mysql> SHOW PROCESSLIST\G
*************************** 2. row ***************************
Id: 2
User: root
Host: localhost:32931
db: NULL
Command: Binlog Dump
Time: 94
State: Has sent all binlog to slave; waiting for binlog to
be updated
Info: NULL
Здесь поток с идентификатором 2 - это поток репликации, созданный для подклю-
ченного подчиненного сервера. Из информации следует, что все необработанные изме-
нения данных отправлены подчиненному серверу, и что главный ожидает поступления
новых изменений.
Н а подчиненном сервере вывод SHOW PROCESSLIST выглядит, как показано ниже:
mysql> SHOW PROCESSLIST\G
*************************** 2. row ***************************
Id: 10
User: system user
Host:
db: NULL
Command: Connect
Time: 11
State: Waiting for master to send event
Info: NULL

Id: 11
User: system user
Host:
db: NULL
Command: Connect
Time: 11
State: Has read all relay log; waiting for the slave I/O
thread to update it
Info: NULL
Эта информация говорит о том, что поток с идентификатором 10 - это поток ввода-
вывода, который взаимодействует с ведущим сервером, а поток с идентификатором 11 -
поток SQL, обрабатывающий изменения, сохраненные в трансляционном журнале. В
настоящий момент оба потока простаивают, ожидая будущих изменений.
Следует отметить, что значение столбца Time отображает, насколько давно подчи-
ненный сервер сравнивался с главным. См. раздел 5.9.
5.3. Детали реализации процесса репликации 369

5.3.1. Состояние потока репликации главного сервера


В следующем списке перечислены наиболее общие состояния потока Binlog Dump
главного сервера, которые могут появляться в столбце State. Если вы не наблюдаете
каких-либо потоков Binlog Dump на главном сервере, значит, репликация не выполняет-
ся. То есть в данный момент ни один подчиненный сервер не подключен.
• Sending binlog event to slave (Событие отправки бинарного журнала подчи-
ненному серверу).
Бинарный журнал содержит события; событие - это обычно оператор обновления
данных, плюс некоторая добавочная информация. Поток считывает события из
журнала и отправляет их подчиненному серверу.
• Finished reading one binlog; switching to next binlog (Завершение чтения
очередного бинарного журнала; переключение на следующий бинарный журнал).
Поток завершил чтение файла бинарного журнала и открывает следующий такой
файл, чтобы отправить его подчиненному серверу.
• Has sent a l l binlog to slave; waiting for binlog to be updated (Все би-
нарные журналы отправлены подчиненному серверу; ожидание бинарного журна-
ла для обновления).
Поток прочитал все отложенные изменения из бинарных журналов и отправил их
подчиненному серверу. Это состояние простоя, с ожиданием появления новых со-
бытий в бинарном журнале, появляющихся в результате выполнения операторов
изменения данных, которые выполняются на главном сервере.
• Waiting to finalize termination (Ожидание звершения).
Очень кратковременное состояние, которое случается при останове потока.

5.3.2. Состояние потока репликации ввода/вывода


подчиненного сервера
В следующем списке перечислены наиболее общие состояния, которые можно уви-
деть в столбце State для потока ввода/вывода подчиненного сервера. Начиная с версии
MySQL 4.1.1, это состояние также может присутствовать и в столбце Slave_IO_State,
отображаемом оператором SHOW SLAVE STATUS. To есть теперь вы можете получить хо-
роший обзор того, что происходит, используя только SHOW SLAVE STATUS.
• Connecting to master (Соединение с главным сервером).
Поток пытается подключиться к главному серверу.
• Checking master version (Проверка версии главного сервера).
Очень кратковременное состояние, в котором поток пребывает непосредственно
после того, как подключение установлено.
• Registering slave on master (Регистрация подчиненного сервера на главном сервере).
Также очень кратковременное состояние после установления соединения.
• Requesting binlog dump (Запрос дампа бинарного журнала).
Кратковременное состояние, возникающее после установления соединения. Поток
посылает главному серверу запрос содержимого бинарного журнала, начиная с
заданного имени файла журнала и позиции в нем.
370 Глава 5. Репликация в MySQL

• Waiting to reconnect after a failed binlog dump request (Ожидание повтор-


ного соединения после сбоя запроса дампа бинарного журнала).
Если запрос выдал сбой (из-за разрыва соединения), поток переходит в это со-
стояние, при котором находится в спящем режиме, периодически пытаясь вос-
становить соединение. Интервал между попытками может быть указан опцией
—master-connect-retry.
• Reconnecting after a failed binlog dump request (Повторное соединение по-
сле сбоя запроса дампа бинарного журнала).
Поток пытается восстановить соединение с главным сервером.
• Waiting for master to send event (Ожидание событий от главного сервера).
Поток подключился к главному серверу и ожидает появления событий из бинар-
ного журнала. В этом состоянии он может находиться длительное время, если
главный сервер простаивает. Если ожидание длится slave_read_timeout секунд,
происходит таймаут. В этом случае поток предполагает, что соединение разорва-
но и предпринимает попытки повторного подключения.
• Queueing master event to the relay log (Запрос события главного сервера для
журнала ретрансляции).
Поток прочитал событие и копирует его в журнал ретрансляции, чтобы поток
SQL мог его обработать.
• Waiting to reconnect after a failed master event read (Ожидание повторно-
го соединения после сбоя в чтении события главного сервера).
Произошла ошибка при чтении (по причине отключения). Поток переходит в ре-
жим ожидания на master-connect-retry секунд и затем повторяет попытку под-
ключения.
• Reconnecting after a failed master event read (Повторное соединение после
сбоя в чтении события главного сервера).
Поток пытается восстановить соединение с главным сервером. Когда соединение
устанавливается, поток переходит в состояние Waiting for master to send
event.
• Waiting for the slave SQL thread to free enough relay log space (Ожида-
ние, пока поток SQL подчиненного сервера освободит достаточно места в журна-
ле ретрансляции).
Вы используете ненулевое значение лимита relay_log__space_limit, и журналы
ретрансляции выросли настолько, что их общий размер превысил это значение.
Поток ввода-вывода ожидает, пока поток SQL не освободит достаточно места, об-
работав накопившиеся в журналах ретрансляции события, чтобы иметь возмож-
ность удалить часть из них.
• Waiting for slave mutex on exit (Ожидание семафора завершения от подчи-
ненного сервера).
Очень кратковременное состояние при останове потока.
5.3. Детали реализации процесса репликации 371

5.3.3. Состояние потока SQL репликации


подчиненного сервера
В следующем списке перечислены наиболее общие состояния, которые можно уви-
деть в столбце State для потока SQL подчиненного сервера:
• Reading event from the relay log (Чтение события из журнала ретрансляции).
Поток читает событие из журнала ретрансляции перед началом его обработки.
• Has read a l l relay log; waiting for the slave I/O thread to update i t
(Прочитаны весь журнал ретрансляции; ожидание, пока поток ввода-вывода не
обновит журнал).
Поток обработал все события из файлов журнала ретрансляции и ждет, когда по-
ток ввода-вывода запишет туда новые события.
• Waiting for slave mutex on exit (Ожидание семафора завершения от подчи-
ненного сервера).
Очень кратковременное состояние при останове потока.
Столбец State для потока SQL может также показывать текст оператора. Это означа-
ет, что он прочитал событие из журнала ретрансляции, извлек из него оператор и запус-
тил его на выполнение.

5.3.4. Журнал ретрансляции и файлы состояния


По умолчанию журналы ретрансляции используют имена файлов в форме
имя хоста-relay-bin. ллл, где имя_хоста — это имя подчиненного сервера, а ллл — после-
довательный номер.
Последовательные файлы журналов ретрансляции используют последовательные
номера, начиная с 001. Подчиненный сервер учитывает текущие используемые журналы
в файле индекса. Имя файла индекса по умолчанию формируется как имя_хоста-re lay-
bin, index. По умолчанию все эти файлы создаются в каталоге данных подчиненного
сервера. Имена файлов по умолчанию могут быть изменены с помощью опций сервера
—relay-log и —relay-log-lindex. См. раздел 5.8.
Файлы журналов ретрансляции имеют тот же формат, что и бинарные журналы, по-
этому для их чтения вы можете использовать mysqlbinlog. Журналы ретрансляции ав-
томатически удаляются потоком SQL немедленно после того, как он выполнит все запи-
санные в журналах события и больше в них не нуждается. Не существует никакого явно-
го механизма удаления журналов ретрансляции, поскольку поток SQL заботится об
этом. Однако, начиная с MySQL 4.0.14, команда FLUSH LOGS осуществляет ротацию этих
журналов, что влияет на момент удаления их потоком SQL.
Новый журнал ретрансляции создается при следующих условиях:
• Когда поток ввода-вывода запускается первый раз после старта подчиненного
сервера (В MySQL 5.0 новый журнал ретрансляции создается при каждом старте
потока ввода-вывода, а не только первый раз.)
• Когда журналы сбрасываются, например, командой FLUSH LOGS или mysqladmin
flash-logs. (Это приводит к созданию нового журнала ретрансляции только в
версии MySQL 4.0.14.)
372 Глава 5. Репликация в MySQL

• Когда размер текущего журнала ретрансляции становится слишком большим.


Значение "слишком большой" определяется следующим образом:
• max_relay_log_size, если max_relay_log_size > 0.
• max_binlog_size, если max_relay_log_size = 0, или версия MySQL, предшест-
вующая 4.0.14.
Подчиненный сервер репликации создает два дополнительных маленьких файла в ка-
талоге данных. Это файлы состояния, и по умолчанию они называются roaster.info и
relay-log.info.
Эти файлы содержат информацию, подобную той, что выводит команда SHOW SLAVE
STATUS. Как дисковые файлы, они переживают останов подчиненного сервера и при сле-
дующем запуске предоставляют ему информацию о том, на каком месте остановилось
чтение бинарных журналов главного сервера и на каком - обработка его собственных
журналов ретрансляции.
Файл master.info обновляется потоком ввода-вывода. До MySQL 4.1 соответствие
между строками в файле и столбцами, которые выводит SHOW SLAVE STATUS, было таким:
Строка Описание
1 Master_Log__File
2 Read_Master_Log_Pos
3 Master_Host
4 Master_User
5 Пароль (не выводится командой SHOW SLAVE STATUS)
6 Master_Port
7 Connect__Retry
Начиная с MySQL 4.1, файл включает количество строк и информацию об опциях SSL:
Строка Описание
1 Количество строк в файле
2 Master_Log_File
3 Read_Master_Log_Pos
4 Master_Host
5 MasterJJser
6 Пароль (не выводится командой SHOW SLAVE STATUS)
7 Master_Port
8 Connect_Retry
9 Master_SSL_Allowed
10 Master_SSL_CA_File
11 Master_SSL_CA_Path
12 Master_SSL_Cert
13 Master_SSL_Cipher
14 Master_SSL_Key
Файл relay-log.info обновляется потоком SQL. Соответствие между строками в
файле и столбцами, выводимыми командой SHOW SLAVE STATUS, выглядит следующим
образом:
5.4. Настройка репликации 373

Строка Описание
1 Relay_Log_File
2 Relay_Log_Pos
3 Relay_Master_Log_File
4 Exec_Master_Log_Pos
Когда выполняется резервное копирование данных подчиненного сервера, содержи-
мое этих файлов также нужно копировать вместе с файлами журналов ретрансляции.
После восстановления из резервной копии эти файлы понадобятся для продолжения ре-
пликации. Если вы потеряете файлы журналов ретрансляции, но у вас останется файл
relay-log.info, вы можете определить по нему, насколько далеко продвинулся поток
SQL в чтении и выполнении обновлений бинарного журнала главного сервера. Затем
МОЖНО выдать CHANGE MASTER ТО вместе С опциями MASTER_LOG_FILE и MASTER_LOG_POS,
чтобы заставить подчиненный сервер перечитать бинарный журнал главного сервера,
начиная с заданного места. Это требует, чтобы бинарный журнал на главном сервере все
еще существовал.
Если вашему подчиненному серверу приходится реплицировать операторы LOAD
DATA INFILE, вы должны будете также создать резервные копии всех файлов SQL_LOAD-*,
находящиеся в каталоге, который подчиненный сервер использует для этих целей. Эти
файлы понадобятся ему для продолжения репликации прерванных операторов LOAD DATA
INFILE. Местоположение каталога задается опцией —slave-load-tmpdir. Если каталог
не указан, по умолчанию им будет значение переменной tmpdir.

5.4 Настройка репликации


Здесь представлено краткое описание настройки полной репликации вашего текуще-
го сервера MySQL. Предполагается, что вам нужно реплицировать все базы данных, и
вы никогда ранее не выполняли конфигурирование репликации. Вам придется ненадолго
остановить главный сервер, чтобы выполнить шаги, описанные ниже.
Процедура описана для случая настройки единственного подчиненного сервера, од-
нако она применима и для настройки множества подчиненных серверов.
Хотя этот метод и самый простой для настройки подчиненного сервера, однако, не
единственный. Например, если у вас уже есть снимок данных главного сервера, главный
сервер имеет набор серверных идентификаторов и бинарная регистрация на нем вклю-
чена, вы можете настроить подчиненный сервер без останова главного сервера, и даже
без блокировки обновлений на нем. Более подробная информация по этому поводу
представлена в разделе 5.9.
Если вы собираетесь администрировать процесс репликации MySQL, рекомендуем
тщательно прочитать всю настоящую главу и попробовать выполнить все инструкции.
Вы также должны ознакомиться со всеми опциями запуска репликации, описанными в
разделе 5.8.
Помните, что эта процедура и некоторые SQL-операторы, упоминаемые далее, ссы-
лаются на привилегию SUPER. До версии MySQL 4.0.2 вместо нее использовалась приви-
легия PROCESS.
1. Убедитесь, что у вас установлены последние версии MySQL на главном и подчи-
ненном серверах, и что эти версии совместимы, воспользовавшись таблицей из
раздела 5.5. Не присылайте нам сообщений об ошибках до тех пор, пока не убеди-
тесь в наличии проблемы в самом последнем выпуске.
374 Глава 5. Репликация в MySQL

2. Настройте пользовательскую учетную запись на главном сервере, которую смо-


жет использовать подчиненный сервер для подключения. Этой учетной записи
должна быть предоставлена привилегия REPLICATION SLAVE. Если упомянутая
учетная запись будет применяться только для репликации (что рекомендуется),
вы не должны выдавать ей никаких дополнительных привилегий. Предположим,
что ваш домен называется mydomain.com, и вы хотите создать учетную запись с
именем r e p l , чтобы подчиненные серверы смогли ее использовать для доступа к
главному серверу с любого хоста вашего домена, указывая в качестве пароля
s l a v e p a s s . Чтобы создя-^ учетную запись, выполните следующий оператор
GRANT:
mysql> GRANT REPLICATION SLAVE ON * . *
-> TO f repl'@'%.mydomain.com 1 IDENTIFIED BY ' s l a v e p a s s 1 ;
В версии MySQL, предшествующей 4.0.2, привилегии REPLICATION SLAVE не су-
ществовало. В место нее нужно было выдавать привилегию FILE:
mysql> GRANT FILE ON * . *
-> TO 'repl'@'%.mydomain.com' IDENTIFIED BY ' s l a v e p a s s ' ;
Если вы планируете использовать операторы LOAD TABLE FROM MASTER и LOAD
DATA FROM MASTER с хоста подчиненного сервера, то этой учетной записи
потребуется выдать дополнительные привилегии:
• Глобальные привилегии SUPER и RELOAD.
• Привилегию SELECT на все таблицы, которые вы хотите загружать. Любые
таблицы главного сервера, на которых учетная запись не сможет выполнить
оператор SELECT, будут проигнорированы оператором LOAD DATA FROM MASTER.
3. Если вы применяете только таблицы My ISAM, сбросьте все таблицы и установите
блокировку на запись, выполнив команду FLUSH TABLES WITH READ LOCK:
mysql> FLUSH TABLES WITH READ LOCK;
Оставьте работать клиентскую программу, из которой была выдана команда FLUSH
TABLES, чтобы блокировка по чтению осталась в силе. (Если вы выйдете из кли-
ентской программы, блокировка будет снята.) Затем подготовьте снимок данных с
главного сервера.
Самый простой способ сделать снимок - воспользоваться программой архивации
и создать бинарную резервную копию базы данных в каталоге данных главного
сервера. Сгодится, например, t a r в среде Unix или же PowerArchiver, WinRAR,
WinZIP или подобная в среде Windows. Чтобы с помощью tar создать архив,
включающий все базы данных, перейдите в каталог данных главного сервера, по-
сле чего выполните следующую команду:
shell> tar -cvf /tmp/mysql-snapshot.tar .
Если вы хотите, чтобы в архив была включена только база данных t h i s d b , вы-
полните вместо приведенной выше такую команду:
shell> tar -cvf /tmp/mysql-snapshot.tar ./this_db
Затем скопируйте архивный файл в каталог /tmp на хосте подчиненного сервера.
На этой машине перейдите в каталог данных подчиненного сервера и распакуйте
архив следующей командой:
5.4. Настройка репликации 375

shell> tar -xvf /trap/mysql-snapshot.tar


Возможно, вы не захотите реплицировать базу данных mysql, если подчинен-
ный сервер имеет другой набор пользовательских учетных записей, чем тот,
что есть у главного сервера. В этом случае вы должны исключить его из архива.
Также вам незачем включать в архив файлы журналов, а также master.info или
relay-log.info. Пока действует блокировка по чтению, установленная командой
FLUSH TABLES WITH READ LOCK, прочитайте значение имени текущего бинарного
журнала и смещения на главном сервере:
m y s q l > SHOW MASTER STATUS;
+ + + + +
I File I Position | Binlog_Do_DB | Binlog_Ignore_DB |
+ + + + +
I mysql-bin.003 | 73 | test | manual,mysql |
+ + + + +

В столбце File представлено имя файла журнала, а в столбце Position - смеще-


ние. В данном примере показано имя mysql-bin.003 и смещение 73. Запишите эти
значения. Они понадобятся позже, при настройке подчиненного сервера. Эти значе-
ния представляют собой координаты репликации, с которых подчиненный сервер
должен начать обработку новых изменений, полученных от главного сервера.
После того, как вы получите снимок и зафиксируете имя журнала и смещение,
можно снять блокировку и разрешить проведение изменений:
m y s q l > UNLOCK TABLES;
Если вы применяете таблицы InnoDB, то в идеальном случае должны использовать
инструмент InnoDB Hot Backup. Он делает полный снимок, не требуя установки
каких-либо блокировок на главном сервере, и записывает имя журнала и смеще-
ние, соответствующие снимку, который будет использоваться позже на подчи-
ненном сервере. InnoDB Hot Backup - это дополнительный коммерческий (плат-
ный) инструмент, который не входит в состав стандартного дистрибутива MySQL.
С детальной информацией и снимками экранов этого инструмента можно ознако-
миться на его домашней странице h t t p : / /www. innodb. com/manual. php.
Если не использовать InnoDB Hot Backup, то самый быстрый способ получения
бинарного снимка таблиц InnoDB предполагает останов главного сервера и копи-
рование файлов данных InnoDB, журнальных файлов и файлов определения таб-
лиц (.frm). Чтобы записать имя текущего журнала и значение смещения, выпол-
ните следующие команды перед остановкой сервера:
m y s q l > FLUSH TABLES WITH READ LOCK;
m y s q l > SHOW MASTER STATUS;
Записи имени и смещения, полученные командой SHOW MASTER STATUS, будут вы-
глядеть так же, как было показано выше. После этого остановите сервер без сня-
тия блокировки таблиц, чтобы гарантировать, что сервер был остановлен в со-
стоянии, соответствующем записанным значениям имени журнала и смещения:
shell> mysqladmin -u root shutdown
Альтернативный способ, который работает как для MylSAM-, так и для innoDB-
таблиц, предусматривает использование SQL-дампа главного сервера вместо би-
376 Глава 5. Репликация в MySQL

нарной копии, как было описано выше. Для этого выполните команду mysqldump
—master-data на главном сервере, а позже загрузите файл SQL-дампа в базу дан-
ных подчиненного сервера. Однако этот способ медленнее, чем в случае бинар-
ных данных.
Если главный сервер ранее был запущен без включенной опции —log-bin, имя
журнала и позиция смещения, показанная командой SHOW MASTER STATUS или
mysqldump, будут пустыми. В этом случае значениями, которые вам понадобятся
позже при настройке репликации на подчиненном сервере, будут пустая строка
(")и4.
4. Убедитесь, что раздел [mysqld] в файле my.cnf на хосте главного сервера вклю-
чает опцию log-bin. Там же должна быть указана опция зегчег-1с!=идентифика-
тор главного сервера, где идентификатор_главного_сервера — положительное
целое число от 1 до 2 3 2 - 1. Например:
[mysqld]
log-bin
server-id=l
Если эти опции не указаны, добавьте их и перезапустите сервер.
5. Остановите сервер, который предполагается сделать подчиненным, и добавьте в
его файл my. cnf следующие строки:
[mysqld]
server-i 6.=идентифика тор_подчиненного_ серв ера
Значение идентификатор_подчиненного_сервера, как и идентификатор_глав-
ного_сервера, должно быть положительным целым числом из диапазона от 1 до
2 3 2 - 1. Вдобавок очень важно, чтобы идентификатор подчиненного сервера отли-
чался от идентификатора главного сервера, например:
[mysqld]
server-id=2
Если вы настраиваете несколько подчиненных серверов, каждый из них должен
иметь уникальное значение serverid, отличающееся от того, что указано для глав-
ного, и тех, что указаны для остальных подчиненных серверов. Воспринимайте эти
идентификаторы как нечто, подобное IP-адресам. Они уникальным образом иден-
тифицируют каждый сервер в рамках сообщества партнеров репликации.
Если вы не укажете значение server_id, оно будет установлено равным 1, если не
определен master-host, и 2 - в противном случае. Заметьте, что в случае, если
server_id будет пропущено, главный сервер будет отвергать попытки подключе-
ния от всех подчиненных серверов, и подчиненные серверы не смогут соединить-
ся с ним. Поэтому пропускать server-id будет правильно только в случае резерв-
ного копирования с бинарными журналами.
6. Если вы выполняете бинарное резервное копирование данных главного сервера,
переместите эти копии в каталог данных подчиненного сервера до его запуска.
Убедитесь в корректности набора привилегий доступа к файлам и каталогам.
Пользователь подчиненного сервера, от имени которого запускается сервер
MySQL, должен иметь права на чтение и запись файлов, так же, как и пользова-
тель главного.
5.4. Настройка репликации 377

Если вы выполняете резервное копирование с помощью mysqldump, запускайте


подчиненный сервер первым (см. следующий шаг).
7. Запустите подчиненный сервер. Если ранее репликация на него выполнялась, за-
пустите его с опцией — s k i p - s l a v e - s t a r t , чтобы он не предпринимал немедлен-
ных попыток соединения с главным сервером. Возможно, имеет смысл запустить
подчиненный сервер с опцией —log-warnings, чтобы можно было получать более
подробные сообщения о возникающих проблемах (например, связанных с сетью
или подключением).
8. Если вы выполнили бинарное резервное копирование данных главного сервера с
помощью mysqldump, загрузите файл дампа на подчиненный сервер:
s h e l l > mysql -u r o o t -p < dump_file.sql
9. Выполните следующие операции на подчиненном сервере, указав конкретные
значения опций для своей системы:
mysql> CHANGE MASTER TO
-> MASTER_HOST=' имя_хоста_главного_сервера',
-> MASTER_USER='имя_пользователя_репликации',
-> MASTER_PASSWORD='лароль_релликации ' ,
-> MASTER_LOG_FILE= * имя_файла_записанного_журнала%,
-> MASTER_LOG_POS=лозиция_в_залисаняом_журнале;
Ниже показаны максимальные длины строковых опций:
MASTERJiOST 60
MASTERJJSER 16
MASTER_PASSWORD 32
MASTER_LOG_FILE 255

10. Запустите потоки репликации подчиненного сервера:


mysql> START SLAVE;
После выполнения этой процедуры подчиненный сервер должен подключиться к
главному и захватить все изменения, которые произошли с момента получения первона-
чального снимка данных.
Если вы забудете установить на главном сервере значение server-id, подчиненные
серверы не смогут к нему подключиться.
Если вы забудете установить на подчиненном сервере значение server-id, то полу-
чите следующее сообщение об ошибке в его журнале ошибок:
Warning: You should set server_id to a non-0 value if master_host is set; We
force the server id to 2, but this MySQL server will not act as a slave.
Предупреждение: Вы должны установить server_id в ненулевое значение, если
установлен master_host; server_id принудительно установлен в 2, однако этот
сервер MySQL не будет действовать в качестве подчиненного.
Там же вы найдете сообщения об ошибках, если подчиненный сервер не сможет под-
ключиться к подчиненному по каким-то другим причинам.
Как только подчиненный сервер начинает репликацию, в его каталоге данных появ-
ляются два файла - один с именем m a s t e r . i n f o , а другой - с именем r e l a y - l o g . i n f o .
Подчиненный сервер использует эти файлы для отслеживания, какую часть бинарного
журнала главного сервера он успел обработать. Не удаляйте и не редактируйте эти
файлы за исключением ситуаций, когда вы точно знаете, что делаете, и понимаете воз-
378 Глава 5. Репликация в MySQL

можные последствия своих действий. И даже в этом случае предпочтительно использо-


вать команду CHANGE MASTER TO.
На заметку!
Й, Содержимое файла master. i n f o перекрывает значение некоторых опций, указанных в команд-
р ной строке или в файле my. cnf (см. раздел 5.8).
Как только вы получите снимок, можете использовать его для настройки других под-
чиненных серверов, выполнив соответствующую часть только что описанной процеду-
ры. Нет необходимости готовить другой снимок данных главного сервера, можно ис-
пользовать один и тот же для всех подчиненных серверов.

5.5. Совместимость репликации между


версиями MySQL
Оригинальный формат бинарных журналов был разработан в версии MySQL 3.23. Он
изменялся в версии MySQL 4.0, а затем - в версии MySQL 5.0. Это имеет некоторые по-
следствия, если вы обновляете серверы, участвующие в репликации, как описано в раз-
деле 5.6.
В том, что касается репликации, любые выпуски MySQL 4.1.x и MySQL 4.0.x иден-
тичны, так как они имеют одинаковый формат бинарных журналов. Таким образом, лю-
бые серверы этих версий совместимы, и репликация между ними должна работать без
проблем. Исключением из этого правила является то, что выпуски MySQL от 4.0.0 до
4.0.2 были ранними, "сырыми", и поэтому использоваться не должны. (Такими были
альфа-версии серии выпусков 4.0. Их совместимость описана в документации, постав-
ляемой с дистрибутивами.) В табл. 5.1 описывается совместимость репликации глав-
ный/подчиненный между различными версиями MySQL.

Таблица 5.1. Совместимость репликации в различных версиях MySQL


Главный сервер Главный сервер вер-
версии 3.23.33 сии 4.0.3 и выше или Главный сервер
и выше любой версии 4.1 .х версии 5.0
Подчиненный сервер Да Нет Нет
версии 3.23.33 и выше
Подчиненный сервер Да Да Нет
версии 4.0.3 и выше
Подчиненный сервер Да Да Да
версии 5.0.0

В качестве основного правила, мы рекомендуем использовать последние версии


MySQL, поскольку средства репликации постоянно развиваются. Также мы рекоменду-
ем устанавливать MySQL одной и той же версии на главном и на подчиненных серверах.

5.6. Модернизация установок репликации


Когда вы модернизируете серверы, участвующие в репликации, процедура обновле-
ния зависит от текущих версий сервера и версий, до которых происходит обновление.
5.6. Модернизация установок репликации 379

5.6.1. Модернизация репликации до версии 4.0 или 4.1


Этот раздел посвящен модернизации репликации от MySQL 3.23 до MySQL 4.0 или
4.1. Сервер версии 4.0 должен иметь номер выпуска не ниже 4.0.3, как было описано в
разделе 5.5.
При выполнении модернизации главного сервера от версии MySQL 3.23 до версии
4.0 или 4.1, первым делом следует убедиться, что все подчиненные серверы уже модер-
низированы до версии 4.0 или 4.1. Если это еще не сделано, обновите сначала подчинен-
ные серверы. Остановите каждый из них, выполните модернизацию, перезапустите сами
серверы и перезапустите репликацию.
Модернизацию можно провести безопасно в соответствии с описанной ниже проце-
дурой, при этом предполагается, что на главном сервере установлена версия MySQL
3.23, а на всех подчиненных серверах - версия MySQL 4.0 или 4.1. Имейте в виду, что
после того, как главный сервер будет модернизирован, вы не должны перезапускать ре-
пликацию, используя старые бинарные журналы из версии 3.23, поскольку это может
вызвать сбои на подчиненных серверах версий 4.0 и 4.1.
1. Заблокируйте все обновления на главном сервере с помощью команды FLUSH
TABLES WITH READ LOCK.
2. Подождите, пока подчиненные серверы обработают все накопившиеся изменения,
полученные от главного сервера. Используйте команду SHOW MASTER STATUS на
главном сервере для получения информации о его текущем бинарном журнале и
позиции в нем. Затем для каждого подчиненного сервера используйте полученные
значения в команде SELECT MASTER_POS_WAIT(). Это заблокирует подчиненный
сервер до тех пор, пока он не освободится. После этого выдайте команду STOP
SLAVE на подчиненном сервере.
3. Остановите главный сервер и модернизируйте его до версии MySQL 4.0 или 4.1.
4. Перезапустите главный сервер и запишите имя вновь созданного им файла бинар-
ного журнала. Вы можете получить это имя с помощью команды SHOW MASTER
STATUS на главном сервере. Затем выполните следующие команды на каждом из
подчиненных серверов:
mysql> CHANGE MASTER TO MASTER_LOG_FILE=' имя_бинарного_журнала',
-> MASTERJLOG_POS=4;
mysql> START SLAVE;

5.6.2. Модернизация репликации до версии 5.0


Этот раздел посвящен модернизации репликации от версии MySQL 3.23, 4.0 или 4.1
до версии 5.0.0. Сервер MySQL 4.0 должен иметь номер выпуска не ниже 4.0.3, как опи-
сывалось в разделе 5.5.
Первое, что следует иметь в виду - MySQL 5.0.0 является альфа-выпуском. Он пред-
назначен для того, чтобы работать лучше предшествующих версий (проще выполнять
модернизацию, осуществлять репликацию некоторых важных переменных сеанса, на-
пример, sqljnode). Однако он пока еще недостаточно хорошо протестирован. Как и в
отношении любого альфа-выпуска, мы пока не рекомендуем использовать его в ответст-
венной производственной среде.
При выполнении модернизации главного сервера от MySQL 3.23, 4.0 или 4.1 до вер-
сии 5.0.0, первым делом следует убедиться, что все подчиненные уже модернизированы
380 Глава 5. Репликация в MySQL

до версии MySQL 5.O.O. Если это еще не сделано, обновите сначала подчиненные серве-
ры. Остановите каждый из них, проведите модернизацию, перезапустите сами серверы и
перезапустите репликацию. Подчиненные серверы 5.0.0 могут читать старые бинарные
журналы, которые были записаны до обновления, и обрабатывать их содержимое. Фай-
лы журналов ретрансляции на подчиненных серверах будут иметь формат 5.0.0.
После модернизации подчиненных серверов остановите главный сервер, обновите
его до версии 5.0.0 и затем перезапустите. MySQL 5.0.0 может читать старые бинарные
журналы, которые были записаны до обновления, и отправлять их подчиненным серве-
рам MySQL 5.O.O. Подчиненные серверы распознают старый формат и корректно его
обработают. Бинарные журналы, записанные главным сервером после обновления, бу-
дут иметь правильный формат 5.0.0, и подчиненные серверы также его правильно обра-
ботают.
Другими словами, не нужно принимать каких-то особых мер при модернизации до вер-
сии 5.0.0, кроме того, что подчиненные серверы должны быть обновлены раньше главно-
го. Имейте в виду, что возврат к версии, предшествующей 5.0.0, не будет столь простым.
Вы должны будете убедиться, что все бинарные и журналы ретрансляции полностью об-
работаны, и вы можете их удалить прежде, чем начнете возврат к старой версии.

5.7. Возможности репликации


и известные проблемы
В приведенном ниже списке перечислены поддерживаемые и неподдерживаемые на
сегодняшний день функции. Дополнительная информация о репликации, касающаяся
InnoDB, содержится в разделе 9.7.5.
• Репликация корректно выполняется со значениями AUTO_INCREMENT,
LAST_INSERT_ID() И TIMESTAMP.

• Функции USER(), UUIDO и LOAD_FILE() реплицируются без изменений, и по-


этому на подчиненном сервере работают ненадежно. Это также верно для
CONNECTION_ID() на подчиненных серверах до версии 4.1.1. Новая функция
PASSWORD () хорошо реплицируется на главных серверах версии 4.1.1 и выше, под-
чиненные также должны быть версии 4.1.1 и выше, чтобы принимать ее. Если ис-
пользуются более старые подчиненные серверы, и есть необходимость выпонять
репликацию PASSWORD () с главного сервера версии 4.1.x, вы должны запустить
главный сервер с опцией --old-password, чтобы он использовал старую реализа-
цию функции PASSWORD(). (Имейте в виду, что реализация PASSWORD() в MySQL
4.1.0 отличается от всех других версий MySQL. В средах с репликацией примене-
ния версии MySQL 4.1.0 лучше избегать.)
• Переменная FOREIGNKEYCHECKS реплицируется, начиная с MySQL 4.0.14. Пере-
менные sqljnode, UNIQUE_CHECKS и SQL_AUTO_IS_NULL реплицируются, начиная с
версии 5.0.0. Переменные SQL_SELECT_LIMIT и table_type пока не реплициру-
ются.
• Необходимо использовать одинаковые наборы символов (—default-character-set)
на главном и подчиненном серверах. В противном случае вы можете получить
ошибку дублирования ключа на подчиненном сервере, поскольку ключ, являю-
щийся уникальным в одном наборе символов, может таковым не оказаться в дру-
гом. Наборы символов будут реплицироваться в версии 5.0.x.
5.7. Возможности репликации и известные проблемы 381

• Есть возможность реплицировать транзакционные таблицы на главном сервере,


используя нетранзакционные на подчиненном сервере. Например, вы можете реп-
лицировать главную таблицу InnoDB как подчиненную MylSAM. Однако если де-
лать это, то можно столкнуться с проблемой, если подчиненный сервер остано-
вится во время выполнения блока BEGIN/COMMIT, так как подчиненный сервер бу-
дет стартовать с начала блока BEGIN. Эта ошибка находится в нашем списке
TODO и будет исправлена в ближайшее время.
• Операторы обновления, которые ссылаются на пользовательские переменные (пе-
ременные в форме @имя_леремеяяой), плохо реплицируются в версиях 3.23 и 4.0.
В версии 4.1 этот недостаток исправлен. Помните, что имена пользовательских
переменных нечувствительны к регистру, начиная с MySQL 5.0. Это нужно при-
нимать во внимание при настройке репликации между версией 5.0 и предшест-
вующими версиями.
• Подчиненный сервер может подключаться к главному, используя SSL, если оба
они имеют версию 4.1.1 или выше.
• Если в операторе CREATE TABLE на главном сервере применяются конструкции
DATA DIRECTORY или INDEX DIRECTORY, те же конструкции применяются на подчи-
ненном сервере. Это может вызвать проблемы, если соответствующий каталог от-
сутствует в файловой системе хоста подчиненного сервера, или же он есть, но не-
доступен подчиненному серверу. Начиная с MySQL 4.0.15, введена опция
sqljnode под названием NO_DIR_IN_CREATE. Если подчиненный сервер работает в
SQL-режиме, включающем эту опцию, он будет просто игнорировать эти конст-
рукции перед репликацией оператора CREATE TABLE. В результате файлы данных и
индексов My ISAM создаются в каталоге таблиц базы данных.
• Хотя мы никогда не слышали о том, чтобы такое случалось, существует теорети-
ческая возможность появления расхождений в данных на главном и подчиненном
серверах, если запрос спроектирован таким образом, что модификация данных
недетерминирована и отдается на усмотрение оптимизатора запросов (это в лю-
бом случае плохая практика, даже вне контекста репликации). Детальное объяс-
нение этой ситуации можно найти в разделе 1.8.7.3.
• До версии M y S Q L 4.1.1 Операторы FLUSH, ANALYZE TABLE, OPTIMIZE TABLE И
REPAIR TABLE не записывались в бинарный журнал, а потому не реплицировались
на подчиненные серверы. Обычно это не является проблемой, потому что эти
операторы не модифицируют данные в таблицах. Однако, в некоторых случаях,
это может приводить к сложностям. Если вы реплицируете таблицы привилегий
из базы данных mysql и обновляете эти таблицы непосредственно, без операторов
GRANT, то должны следом давать команду FLUSH PRIVILEGES, чтобы измененные
привилегии пользователей вступили в силу. Также, если вы используете FLUSH
TABLES, когда переименовываете таблицу My ISAM, являющуюся частью MERGE-
таблицы, то должны вручную выдать команду FLUSH TABLES на подчиненных сер-
верах. Начиная с MySQL 4.1.1, эти операторы фиксируются в бинарном журнале
(если только не будет указан NO_WRITE_TO_BINLOG или его псевдоним LOCAL). Ис-
ключения составляют FLUSH LOGS, FLUSH MASTER, FLUSH SLAVE И FLUSH TABLES
WITH READ LOCK, которые не регистрируются в журнале в любом случае. (Каждый
из упомянутых операторов может привести к проблемам, если их реплицировать
на подчиненный сервер.)
382 Глава 5. Репликация в MySQL

• MySQL поддерживает только один главный сервер и множество подчиненных.


Позже мы планируем добавить алгоритм голосования для автоматической смены
главного сервера, если с текущим что-то неладно. Мы также собираемся предста-
вить процессы "агентов", помогающие балансировать нагрузку путем отправки
операторов SELECT другим подчиненным серверам.
• Когда сервер останавливается и перезапускается, его таблица MEMORY (HEAP) стано-
вится пустой. Начиная с MySQL 4.0.18, главный сервер реплицирует этот эффект
следующим образом: первый раз, когда главный сервер использует таблицу
MEMORY после запуска, он уведомляет подчиненные серверы о том, что таблица
должна быть очищена, записывая в бинарный журнал оператор DELETE FROM для
этой таблицы. Более детальную информацию можно найти в разделе 8.3.
• Временные таблицы реплицируются за исключением случаев, когда вы останав-
ливаете подчиненный сервер (а не только потоки репликации подчиненного сер-
вера), и у вас есть некоторые реплицированные временные таблицы, которые ис-
пользуются в операторах обновления, еще не обработанных на подчиненном сер-
вере. Если вы остановите подчиненный сервер, временные таблицы, которые
нужны этим операторам, станут недоступными после следующего запуска. Чтобы
избежать этой проблемы, не останавливайте подчиненный сервер, пока на нем есть
открытые временные таблицы. Вместо этого используйте следующую процедуру:
1. Введите команду STOP SLAVE.
2. С помощью SHOW STATUS просмотрите значение переменной lave_open_temp_tables.
3. Если ее значение равно 0, выполните команду mysqladmin shutdown для оста-
новки подчиненного сервера.
4. Если ее значение не равно 0, перезапустите потоки репликации подчиненного
сервера командой START SLAVE.
5. Повторите процедуру позже, в надежде на большее везение.
Мы планируем решить эту проблему в ближайшем будущем.
• Безопасно соединять сервера в циклические отношения главный/подчиненный с
помощью опции --log-slave-updates. Помните, однако, что при таком варианте
настройки многие операторы не будут работать корректно, если только ваш кли-
ентский код не написан так, чтобы позаботиться о потенциальных проблемах, ко-
торые могут возникнуть из-за обновлений данных в разном порядке на разных
серверах.
Это означает, что вы можете настроить цепочку репликации таким образом:
А -> В -> С -> А

Идентификаторы сервера закодированы в бинарном журнале, поэтому сервер А


будет знать, что событие, которое он прочитает, изначально было порождено им,
и не станет его обрабатывать. Поэтому бесконечных циклов не будет. Однако эта
циклическая настройка будет работать только тогда, когда вы не производите
конфликтующих между собой обновлений таблиц. Другими словами, если вы
вносите данные и на А, и на С, вы не должны никогда вставлять строку на А,
ключ которой может конфликтовать со строкой, вставленной на С. Также вы не
должны обновлять одни и те же строки на двух серверах, если порядок их обнов-
ления имеет значение.
5.7. Возможности репликации и известные проблемы 383

• Если оператор, выполняющийся на подчиненном сервере, приводит к ошибке, по-


ток SQL прерывается и в журнал ошибок записывается сообщение. Вы должны
затем подключиться к подчиненному серверу вручную, исправить проблему (на-
пример, отсутствующая таблица) и затем запустить START SLAVE.
• Совершенно безопасно останавливать главный сервер и перезапускать его позже.
Если подчиненный сервер теряет соединение с главным, он немедленно пытается
его восстановить. Если ему это не удается, он повторяет попытки периодически
(по умолчанию - каждые 60 секунд; это значение можно изменить с помощью оп-
ции —master-connect-retry). Подчиненный сервер также справляется с пробле-
мами пропадания сети. Однако он известит о проблемах с сетью только в случае,
если не получит от главного никаких данных в течение slave_net_timeout се-
кунд. Если такие отказы кратковременны, вы можете уменьшить значение
slave_net_timeout (см. раздел 4.2.3).
• Остановка подчиненного сервера (штатная) также безопасна, поскольку он отсле-
живает позицию, на которой останавливает работу. Аварийные остановки могут
привести к проблемам, особенно, если дисковый кэш не был сброшен, прежде чем
система остановилась. Устойчивость ваших систем к отказам может быть зна-
чительно повышена, если вы применяете качественные источники бесперебойно-
го питания.
• Из-за нетранзакционной природы таблиц My ISAM существует возможность иметь
оператор, который только частично обновил таблицу и возвратил код ошибки.
Это может случиться, например, при многострочной вставке, когда одна их строк
нарушила ограничение уникальности ключа, либо когда долго выполняющаяся
операция обновления была прервана после того, как обновила только часть строк.
Если подобное случается на главном сервере, поток подчиненного сервера оста-
навливается и ожидает решения администратора базы данных о том, что с этим
делать, если только не окажется, что код ошибки вполне легитимный и выпол-
нение оператора на подчиненном сервере приведет к тому же коду ошибки. Ес-
ли поведение, основанное на проверке кода ошибки, нежелательно, некоторые
или все ошибки могут быть маскированы (проигнорированы) с помощью опции
—slave-skip-errors. Эта опция появилась в MySQL 3.23.47.
• Если вы обновляете транзакционные таблицы из нетранзакционных внутри сег-
мента BEGIN/COMMIT, записи бинарного журнала могут оказаться несинхрони-
зированными, если какой-нибудь поток изменит нетранзакционную таблицу до
завершения транзакции. Это объясняется тем, что транзакция записывается в би-
нарный журнал только при ее фиксации.
• До версии 4.0.15 любое обновление нетранзакционной таблицы записывалось в
бинарный журнал немедленно после его проведения, в то время как транзакцион-
ные обновления записывались после COMMIT, либо не записывались вовсе, если
применялся ROLLBACK. Вы должны принимать это во внимание, когда обновляете и
транзакционные, и нетранзакционные таблицы в пределах одной транзакции (это
имеет значение не только для репликации, но также и в случае, если бинарная ре-
гистрация применяется для резервных копий). В версии 4.0.15 было изменено по-
ведение бинарных журналов транзакций, в которых участвуют таблицы разных
типов, что решило проблему (последовательность операторов в бинарном журна-
ле записывается правильно, даже если применяется ROLLBACK). Проблема, которая
384 Глава 5. Репликация в MySQL

осталась, состоит в том, что когда второй сеанс обновляет нетранзакционную таб-
лицу в то время, когда в первом сеансе не окончена транзакция, то порядок опера-
торов все еще может оказаться неверным, потому что обновление второго сеанса
регистрируется в журнале немедленно после выполнения.
В следующем списке перечислены проблемы репликации в версии MySQL 3.23, ко-
торые были успешно решены в MySQL 4.O.
• LOAD DATA INFILE обрабатывается правильно до тех пор, пока файл данных нахо-
дится на главном сервере во время репликации.
• LOAD DATA LOCAL INFILE более не пропускается на подчиненном сервере, как это
было в версии 3.23.
• В версии 3.23 функция RANDO в операторах обновления данных реплицировалась
неправильно. Используйте RAND {некоторое_неслучайное_выражение), если вы ре-
плицируете обновления с вызовом RAND (). Например, в качестве аргумента RAND ()
можно использовать UNIX_TIMESTAMP ().

5.8. Опции запуска репликации


И на главном, и на подчиненном серверах вы должны использовать опцию server-id
для установки уникального идентификатора репликации. Для каждого главного и под-
чиненного серверов потребуется указать уникальное положительное число в пределах от
1 до 2 3 2 - 1, например, server-id=3.
Опции, которые можно использовать на главном сервере для управления бинарной
регистрацией, описаны в разделе 4.8.4.
Ниже описаны опции, которые можно применять на подчиненном сервере реплика-
ции. Их можно указывать в командной строке или конфигурационном файле.
Некоторые опции репликации подчиненного сервера обрабатываются специальным
образом, в том смысле, что они игнорируются, если на момент старта сервера уже суще-
ствует файл master.info, содержащий собственные значения. Подобным образом обра-
батываются следующие опции:
• —master-host
• —master-user
• —master-password
• —master-port
• —master-connect-retry
Начиная с MySQL 4.1.1, следующие опции также обрабатываются специальным об-
разом:
• —master-ssl
• —master-ssl-ca
• —master-ssl-capath
• —master-ssl-cert
• —master-ssl-cipher
• —master-ssl-key
Формат файла master.info в MySQL 4.1.1 изменился, и теперь включает значения,
соответствующие опциям SSL. Вдобавок, формат этого файла предусматривает, что в
5.8. Опции запуска репликации 385

первой строке указывается общее количество строк в нем. Если вы обновляете старый
сервер до версии 4.1.1, он автоматически обновит файл master.info в соответствии с
новым форматом. Однако если вы возвращаетесь от версии 4.1.1 к более старой, вам
придется вручную убрать первую строку этого файла перед первым запуском сервера.
Помните также, что после возврата к старой версии сервер не сможет больше использо-
вать SSL-соединения для подключения к главному серверу.
Если файл master.info не существует на момент запуска подчиненного сервера, для
этих опций он использует те значения, которые указаны в командной строке или конфи-
гурационном файле. Это случается, когда вы самый первый раз запускаете сервер в ка-
честве подчиненного в процессе репликации, либо после того, как вы даете команду
RESET SLAVE, останавливаете и перезапускаете подчиненный сервер.
Если файл master.info существует на момент старта подчиненного сервера, пере-
данные значения этих опций игнорируются. Вместо них используются значения, прочи-
танные из файла master. info.
Если вы перезапускаете подчиненный сервер с другими значениями опций, которые
соответствуют указанным в master.info, эти новые значения не имеют эффекта, по-
скольку сервер продолжает использовать файл master.info. Чтобы использовать новые
значения, вы должны либо перезапустить сервер снова, удалив файл master.info, или
(что предпочтительнее) с помощью команды CHANGE MASTER TO сбросить значения пря-
мо в процессе работы подчиненного сервера.
Предположим, что вы указали следующую опцию в файле my. cnf:
[mysqld]
master-host=HeKOTopNH_xocT
Первый раз, когда вы запускаете сервер как подчиненный в репликации, он читает и
использует значение этой опции из файла my.cnf. Затем он записывает это значение в
файл master.info. При следующем старте он читает имя хоста главного сервера толь-
ко из файла master. info и игнорирует значение, заданное в конфигурационном файле.
Если вы модифицируете файл my.cnf, чтобы изменить имя хоста главного сервера на
другой_хост, это изменение не возымеет никакого эффекта. Вместо этого следует
воспользоваться оператором CHANGE MASTER TO.
Поскольку сервер отдает предпочтение существующему файлу master.info при чте-
нии описанных опций запуска, возможно, вы предпочтете вообще их не использовать, а
вместо этого указывать их с помощью оператора CHANGE MASTER TO.
В следующем примере продемонстрировано более продуманное применение опций
запуска для конфигурирования подчиненного сервера:
[mysqld]
server-id=2
master-host=db-master.mycompany.com
master-port=3306
master-user=pertinax
master-password=freitag
master-connect-retry=60
report-host=db-slave.mycompany.com
В следующем перечне описаны опции запуска для управления репликацией. Многие
из них могут быть сброшены в процессе работы сервера с помощью команды CHANGE
386 Глава 5. Репликация в MySQL

MASTER TO. Другие, такие как опции —replicate-*, могут быть установлены только при
запуске подчиненного сервера. Мы планируем исправить это.
• —log-slave-updates. Обычно изменения, полученные подчиненным сервером от
главного, не записываются в его бинарный журнал. Эта опция указывает подчи-
ненному серверу, что изменения, которые проводит его поток SQL репликации,
должны регистрироваться в журнале. Чтобы эта опция возымела эффект, подчи-
ненный сервер должен быть запущен с опцией —bin-log, включающей бинарную
регистрацию. —log-slave-updates применяется в случаях, когда нужно постро-
ить цепочку реплицируемых серверов, например, по такой схеме:
А -> В -> С
То есть А служит главным для подчиненного В, а В служит главным для С. Чтобы
эта схема работала, В должен быть одновременно и главным, и подчиненным. Вы
должны запускать и А, и В с опцией --bin-log, чтобы разрешить бинарную реги-
страцию, а В еще и с опцией —log-slave-updates.
• —log-warnings. Заставляет подчиненный сервер печатать больше сообщений о
том, что он делает. Например, он известит вас об успешном восстановлении со-
единения после сбоя сети и сообщит о том, как стартовал каждый из потоков, об-
служивающих репликацию. Эта опция касается не только репликации. Она за-
ставляет генерировать сообщения о многих аспектах активности сервера.
• --master-connect-retry=ceKyjwi. Период времени в секундах, в течение которого
сервер ожидает перед повторными попытками подключиться в случае остановки
главного сервера или отказа сети. Значение, указанное в master.info, имеет при-
оритет, если оно может быть прочитано. Если не установлено явно, принимается
равным 60 секундам.
• —master-host=xocT. Имя хоста или IP-адрес главного сервера репликации. Если
эта опция не указана, потоки репликации подчиненного сервера не запускаются.
Значение, указанное в master. info, имеет приоритет, если может быть прочитано.
• —master-info-f Пе=имя_файла. Имя файла, в который подчиненный сервер запи-
сывает информацию о главном сервере. Значение по умолчанию - mysql.info,
размещенный в каталоге данных.
• —master-password=napcitfb. Пароль пользовательской учетной записи, которую
поток подчиненного сервера использует при подключении к главному серверу.
Значение, указанное в master. info, имеет приоритет, если может быть прочитано.
Если пароль не установлен, он считается пустым.
• —master-port=HOMep_nopTa. Порт TCP/IP, который использует главный сервер
для прослушивания соединений. Значение, указанное в master.info, имеет при-
оритет, если может быть прочитано. Если не установлено, во внимание принима-
ется жестко закодированное в сервере. Если вы не указали другое для configure
при сборке сервера, то оно равно 3306.
• —master-ssl

—master-ssl-capath=имя_кaтaлoгa
—master-ssl-cert=H^3^aj^7a
—master-ssl-cipher=cnHCOK_iuH$poB
5.8. Опции запуска репликации 387

Эти опции используются для настройки защищенного соединения с главным сер-


вером через SSL. Их значения такие же, как и у соответствующих опций --ssl,
—ssl-ca, —ssl-capath, —ssl-cert, —ssl-cipher и —ssl-key, которые описаны
в разделе 4.5.8.5. Значения, указанные в master.info, имеют приоритет, если мо-
гут быть прочитаны. Эти опции работают, начиная с MySQL 4.1.1.
—таз1ег-изег=имя_пользователя. Имя пользовательской учетной записи, кото-
рую поток подчиненного сервера использует при подключении к главному. Учет-
ная запись должна иметь привилегию REPLICATION SLAVE. (До MySQL 4.0.2 вме-
сто этого она должна была иметь привилегию FILE.) Значение, указанное в
master .info, имеет приоритет, если может быть прочитано. Если имя пользовате-
ля не указано, предполагается по умолчанию test.
—max-relay-log-size=#. Для автоматической ротации журналов ретрансляции
(см. раздел 4.2.3). Эта опция действительна, начиная с MySQL 4.0.14.
—read-only. Эта опция запрещает какие-либо изменения данных, кроме тех, что
выполняет поток репликации или пользователь с привилегией SUPER. Может ока-
заться полезным, если необходимо гарантировать, чтобы подчиненный сервер не
допускал никаких обновлений данных от клиентов. Эта опция действительна, на-
чиная с MySQL 4.0.14.
—ге1ау-1од=имя_файла. Имя журнала ретрансляции. По умолчанию принимается
равным имя_хоста-ге1ау-Ып.ллл, где имя_хоста - имя хоста подчиненного сер-
вера, а ллл означает, что файлы журнала ретрансляции создаются в числовой по-
следовательности. Вы можете указать эту опцию, чтобы использовать имена жур-
налов, не зависящие от имени хоста; если файлы журналов получаются слишком
большим (и вы не хотите уменьшать max_relay_log_size), и необходимо помес-
тить их в месте, отличном от каталога данных; если требуется увеличить скорость
за счет распределения нагрузки между дисками.
—ге1ау-1од-1пс1ех=имя_файла. Указывает местоположение и имя файла индекса
журнала ретрансляции. Значение по умолчанию - имя_хоста-ге1ау-Ып. index,
где имя_хоста - имя хоста подчиненного сервера.
—relay-log-infо-И1е=имя_файла. Имя файла, в который подчиненный сервер
записывает информацию о журналах ретрансляции. По умолчанию это relay-
log, info, размещенный в каталоге данных.
—relay-log-purge={0 11}. Включает и отключает автоматическую очистку жур-
налов ретрансляции, как только они становятся не нужны. Значение по умолча-
нию - 1 (включено). Это глобальная переменная, которую можно изменить уста-
новкой SET GLOBAL relay_log_purge.
Эта опция действительна, начиная с MySQL 4.1.1.
--relay-log-space-limit=#. Устанавливает верхний предел общего размера всех
журналов ретрансляции на подчиненном сервере (значение 0 означает "не огра-
ничено"). Это удобно для хостов подчиненного сервера, у которых ограничено
дисковое пространство. Когда предел достигнут, поток ввода-вывода приостанав-
ливает чтение событий из бинарного журнала главного сервера до тех пор, пока
поток SQL не обработает и не удалит некоторые из неиспользуемых файлов жур-
388 Глава 5. Репликация в MySQL

налов ретрансляции. Имейте в виду, что этот предел не абсолютен. Существуют


случаи, когда потоку SQL требуется больше событий, прежде чем он очистит
журналы ретрансляции. В этом случае поток ввода-вывода превысит ограничение
до тех пор, пока поток SQL не сможет их очистить. Если этого не делать, можно
получить взаимную блокировку (что и случалось в версиях MySQL, предшест-
вующих 4.0.13). Вы не должны устанавливать значение —relay-log-space-limit
меньше, чем двойное значение —max-relay-log-size (или —max-bin-log-size,
если --max-relay-log-size равно 0). В этом случае существует вероятность,
что поток ввода-вывода будет ждать свободного пространства, поскольку
—relay-log-space-limit превышен, а поток SQL не будет иметь файлов журна-
лов ретрансляции, которые нужно удалить, и не сможет удовлетворить ожиданий
потока ввода-вывода. Это заставляет поток ввода-вывода временно игнорировать
—relay-log-space-limit.
• —герИсаЬе-<1о-дЬ=имя_базы_данных. Заставляет подчиненный сервер ограничить
репликацию только операторами, для которых базой данных по умолчанию (вы-
бранной оператором USE) является имя_базы__данных. Для указания более чем од-
ной базы данных используйте эту опцию несколько раз, по одному для каждой ба-
зы. Имейте в виду, что это не позволит реплицировать межбазовые операторы,
подобные UPDATE база__данных. таблица SET foo='bar 1 , пока выбрана другая база
данных, или не выбрано никакой. Если нужно, чтобы работали межбазовые об-
новления, убедитесь, что установлен MySQL версии 3.23.28 или более новой, и
используйте —replicate-wild-do-table=HM#_6a3b/^aHHbfx.%. Обязательно озна-
комьтесь с инструкциями, следующими за данным списком опций.
Вот пример того, что не работает, как ожидается: если подчиненный сервер запу-
щен с опцией —replicate-do-db=sales, и вы выполняете следующие операторы
на главном сервере, UPDATE не будет реплицироваться:
USE prices;
UPDATE sales.January SET amount=amount+1000;
Если необходимо, чтобы работали межбазовые обновления, используйте вместо
этой опции —replicate-wild-do-table=HM#_6a3bf^aHHb/x.%.
Основной смысл такого поведения состоит в том, что трудно решить для отдель-
ного оператора, должен он реплицироваться или нет. (Например, если вы исполь-
зуете многотабличные операторы DELETE, или операторы UPDATE, которые затра-
гивают несколько баз данных). Кроме того, гораздо быстрее просто проверить ба-
зу данных по умолчанию.
• —replicate-do-ЬаЫе=имя_базы_данных. имя_таблицы. Указывает подчиненному
серверу ограничиться только репликацией названной таблицы. Чтобы задать бо-
лее одной таблицы, нужно применить эту опцию несколько раз, по одному на ка-
ждую таблицу. Это будет работать и для операторов межбазовых обновлений, в
отличие от —replicate-do-db. Обязательно ознакомьтесь с инструкциями, сле-
дующими за данным списком опций.
• —replicate-ignore-db=HM#_6a3H_4aHHb/x. Указывает подчиненному серверу не
реплицировать операторы, для которых установлена база данных по умолчанию
имя_базы__данных. Чтобы задать более одной базы данных для игнорирования, по-
требуется применить эту опцию несколько раз, по одному на каждую базу. Не
5.8. Опции запуска репликации 389

следует пользоваться этой опцией, если вы применяете межбазовые обновления и


не хотите, чтобы они реплицировались. Обязательно ознакомьтесь с инструкция-
ми, следующими за данным списком опций.
Вот пример того, что не работает, как ожидается: если подчиненный сервер запу-
щен с опцией — replicate-ignore-db=sales, и вы выполняете следующие опера-
торы на главном сервере, UPDATE будет реплицироваться:
USE prices;
UPDATE sales.January SET amount=amount+1000;
Если нужно, чтобы работали межбазовые обновления, используйте вместо этой
опции —replicate-wild-ignore-table=HM#_6a3H^aHHHx. %.
• —г explicate-±дпоге-1аЫе=имя_базы_данных.имя_таблицы. Указывает подчинен-
ному серверу не реплицировать операторы, обновляющие названную таблицу
(даже если любая другая таблица может быть обновлена тем же оператором).
Чтобы задать более одной таблицы, обновление данных которой не нужно репли-
цировать, используйте эту опцию несколько раз, по одному на каждую таблицу.
Это будет работать и для операторов межбазовых обновлений, в отличие от
--replicate-ignore-db. Обязательно ознакомьтесь с инструкциями, следующими
за данным списком опций.
• —replicate-wild-do-table=HM#_6a3b/^aHHHx. имя_таблицы
Указывает подчиненному серверу ограничить репликацию операторами, где имя
любой из обновляемых таблиц соответствует шаблону, состоящему из имени базы
и имени таблицы. Шаблон может содержать символы '%' и '_', которые имеют тот
же смысл, что и в операции сравнения с шаблоном LIKE. Чтобы указать более од-
ной таблицы, используйте эту опцию несколько раз, по одному на каждую табли-
цу. Это будет работать и для операторов межбазовых обновлений. Обязательно
ознакомьтесь с инструкциями, следующими за данным списком опций.
Пример: —replicate-wild-do-table=foo% .bar% будет реплицировать только об-
новления, которые касаются таблиц с именами, начинающимися на bar, из баз
данных, имена которых начинаются на f оо.
Если шаблон имени состоит только из '%', он соответствует любому имени таблицы
и применим к операторам уровня базы данных (CREATE DATABASE, DROP DATABASE и
ALTER DATABASE). Например, если вы используете —replicate-wild-do-table=
f 00%. %, операторы уровня базы данных будут реплицироваться, если имя базы со-
ответствует шаблону f оо%.
Для включения литеральных символов шаблонов для имен базы данных и имен
таблиц сопровождайте их символом обратного косой черты. Например, чтобы ре-
плицировать все таблицы из баз с именами my_own%db, но не трогать таблиц из ба-
зы mylownAABCdb, нужно написать так: —replicate-wild-do-table=my\__own\%db.
Если вы используете опции командной строки, в зависимости от командной обо-
лочки, может понадобиться продублировать обратные косые черты или взять в
кавычки значение опции. Например, для оболочки bash это будет выглядеть так:
—replicate-wild-do~table=my\\_own\\%db.
• —replicate-wild-ignore-table=имя_бaзы_дaнныx.ямя_тaблиць^. Указывает под-
чиненному серверу не реплицировать операторы обновления данных в таблицах,
имена которых соответствуют заданному шаблону. Чтобы указать более одной
390 Глава 5. Репликация в MySQL

таблицы для игнорирования при репликации, используйте эту опцию несколько


раз, по одному на каждую таблицу. Это будет работать и для операторов межба-
зовых обновлений. Обязательно ознакомьтесь с инструкциями, следующими за
данным списком опций.
Пример: --replicate-wild-ignore-table=foo%.bar% не будет реплицировать об-
новления, которые касаются таблиц с именами, начинающимися на bar, из баз
данных, имена которых начинаются на f oo.
Информацию о том, как сравниваются имена с шаблонами можно найти в описании
опции —replicatewild-ignore-table. Инструкции по включению литеральных сим-
волов шаблонов в значение опции те же, что и для —replicate-wild-ignore-table.
• —replicate~rewrite-db=HM#_H3->HM#_B. Указывает подчиненному серверу на
необходимость транслировать имя базы данных по умолчанию (выбранной опера-
тором USE) В ИМЯ ИМЯ_В, если на главном сервере она была имя__из. Это касается
только операторов, работающих с таблицами (отличных от CREATE DATABASE, DROP
DATABASE и ALTER DATABASE), и только если имя_из была базой данных по умолча-
нию на главном сервере. Это не работает для межбазовых обновлений. Имейте в
виду, что трансляция имени базы данных выполняется до того, как проверяются
правила —replicate-*.
Если вы используете эту опцию в командной строке, а символ '>' является управ-
ляющим в вашей командной оболочке, заключите значение опции в кавычки, па-
пример:
shell> mysqld ~replicate-rewrite-db= lt cтapaяБД->яoвaяБЛ м
• —report-host=xocT. Имя хоста или IP-адрес подчиненного сервера, который пе-
редается главному серверу при регистрации. Это значение появляется в выводе
команды SHOW SLAVE HOSTS на главном сервере. Если вы не хотите, чтобы подчи-
ненный сервер регистрировался на главном, не устанавливайте это значение.
Помните, что для главного сервера недостаточно просто прочитать IP-адрес под-
чиненного сервера из сокета TCP/IP после его подключения. Из-за трансляции се-
тевых адресов (NAT) или других обстоятельств, связанных с маршрутизацией,
этот IP-адрес может оказаться некорректным для подключения к подчиненному
серверу с главного сервера или с других хостов.
Эта опция действительна, начиная с MySQL 4.O.O.
• —report-port=HOMep_nopTa. Порт TCP/IP для подключения к подчиненному сер-
веру, который передается главному серверу во время регистрации. Устанавливай-
те эту опцию, если подчиненный прослушивает нестандартный порт, или если у
вас настроен какой-нибудь специальный туннель от главного или от других кли-
ентов к подчиненному. Если вы не уверены, не указывайте эту опцию.
Эта опция действительна, начиная с MySQL 4.O.O.
• —skip-slave-start. Предписывает подчиненному серверу не запускать при стар-
те потоки, обслуживающие репликацию. Чтобы запустить их позже, воспользуй-
тесь оператором START SLAVE.
• —slave_compressed_protocol={0,1}. Если эта опция установлена в I, использу-
ется сжатие протокола взаимодействия между главным и подчиненным сервера-
ми, если они оба поддерживают такое сжатие.
5.8. Опции запуска репликации 391

• —slave-load-tmpdir=HMH^a^a. Имя каталога, в котором подчиненный сервер


создает временные файлы. Эта опция по умолчанию содержит значение, храня-
щееся в системной переменной tmpdir. Когда поток SQL подчиненного сервера
реплицирует оператор LOAD DATA INFILE, он извлекает файл, предназначенный
для загрузки, из журнала ретрансляции в каталог временных файлов, затем за-
гружает его в таблицу. Если файл, загруженный в базу данных на главном сер-
вере, был очень большим, временный файл на подчиненном тоже будет боль-
шим. Поэтому можно посоветовать использовать эту опцию, чтобы подчинен-
ный сервер размещал временные файлы в каталоге, находящемся в файловой
системе, в которой много свободного места. В этом случае вы также можете ис-
пользовать опцию —relay-log, чтобы разместить журналы ретрансляции в той
же файловой системе, потому что журналы ретрансляции также будут огромными.
--slave-load-tmpdir должна указывать на каталог в дисковой системе, а не в па-
мяти. Подчиненный сервер нуждается во временных файлах для репликации опе-
ратора LOAD DATA INFILE, чтобы пережить перезапуск машины. Этот каталог так-
же не должен очищаться автоматически при перезапуске системы.
• —slave-net-timeout=ceKyH^ Время ожидания данных от главного сервера, кото-
рое выдерживает подчиненный сервер перед тем, как прервать чтение из-за раз-
рыва соединения и попробовать подключиться повторно. Первая попытка пред-
принимается немедленно после истечения тайм-аута. Интервал между попытками
устанавливается с помощью опции --master-connect-retry.
• —slave-skip-errors= [код_ошибки1,код_ошибки2,... | a l l ] . Обычно реплика-
ция останавливается, когда возникает ошибка, что дает возможность вручную
устранить несогласованность данных. Эта опция предписывает потоку SQL под-
чиненного сервера продолжать репликацию, когда оператор возвращает одну из
перечисленных в значении опции ошибок.
Не используйте эту опцию, если только полностью не понимаете причин возник-
новения ошибок. Если нет ошибок в настройках репликации, в клиентских про-
граммах и в самом MySQL, ошибки, останавливающие репликацию, никогда не
должны возникать. Неразборчивое применение этой опции может привести к то-
му, что произойдет полная рассинхронизация данных на подчиненном и главном
серверах, и вы не будете иметь понятия почему.
Для указания кодов ошибок нужно использовать числа, сопровождающие сооб-
щения в журнале ошибок подчиненного сервера и в выводе команды SHOW SLAVE
STATUS.
Вы можете (но не должны) также использовать крайне не рекомендуемое значе-
ние a l l , которое заставит подчиненный сервер игнорировать все ошибки и про-
должать работу, независимо от того, что происходит. Нет необходимости гово-
рить, что если вы используете это значение, то никто не сможет дать никаких га-
рантий целостности ваших данных. Не стоит жаловаться, если ваши данные на
подчиненном сервере даже близко не будут похожи на те, что хранятся на глав-
ном. В общем, вас предупредили.
Примеры:
—slave-skip-errors=1062,1053
—slave-skip-errors=all
392 Глава 5. Репликация в MySQL

Правила репликации —replicate-* для определения того, будет ли оператор выпол-


нен на подчиненном сервере или же проигнорирован, оцениваются следующим образом:
1. Есть ли какие-то правила —replicate-do-db или — replicate-ignore-db?
• Да. Проверьте их как — binlog-do-db и —binlog-ignore-db (см. раздел 4.8.4).
Каков результат проверки?
• Игнорировать оператор. Проигнорировать и выйти.
• Выполнить оператор. Не выполнять немедленно, отложить решение, пе-
рейти к следующему шагу.
• Нет. Перейти к следующему шагу.
2. Есть ли какие-то правила --replicate-*-table?
• Нет. Выполнить запрос и выйти.
• Да. Перейти к следующему шагу. Только таблицы, которые должны обнов-
ляться, сравниваются с правилами (INSERT INTO sales SELECT * FROM prices:
только sales будет сравниваться с правилом). Если несколько таблиц должны
обновляться (многотабличный оператор), первая подходящая таблица (подхо-
дящая в смысле "do" или "ignore") побеждает. Таким образом, первая таблица
проверяется на соответствие правилу. Далее, если решение не принято, на
предмет соответствия правилам проверяется вторая таблица и так далее.
3. Есть ли какие-то правила —replicate-do-table?
• Да. Соответствует ли таблица любому из них?
• Да. Выполнить запрос и выйти.
• Нет. Перейти к следующему шагу.
• Нет. Перейти к следующему шагу.
4. Есть ли какие-то правила —replicate-ignore-table?
• Да. Соответствует ли таблица любому из них?
• Да. Игнорировать запрос и выйти.
• Нет. Перейти к следующему шагу.
• Нет. Перейти к следующему шагу.
5. Есть ли какие-то правила —replicate-wild-do-table?
• Да. Соответствует ли таблица любому из них?
• Да. Выполнить запрос и выйти.
• Нет. Перейти к следующему шагу.
• Нет. Перейти к следующему шагу.
6. Есть ли какие-то правила —-replicate-wild-ignore-table?
• Да. Соответствует ли таблица любому из них?
• Да. Игнорировать запрос и выйти.
• Нет. Перейти к следующему шагу.
• Нет. Перейти к следующему шагу.
7. Никаких правил —replicate-* не найдено. Есть ли следующая таблица, которую
нужно проверить на предмет соответствия правилам?
5.9. Часто задаваемые вопросы по репликации 393

• Да. Цикл.
• Нет. Проверены все таблицы, которые нужно обновлять, и соответствия пра-
вилам не найдены. Есть ли правила --replicate-do-table или —replicate-
wild-do-table?
• Да. Игнорировать запрос и выйти.
• Нет. Выполнить запрос и выйти.

5.9. Часто задаваемые вопросы по репликации


Вопрос. Как настроить подчиненный сервер, если главный уже запущен, и нет жела-
ния его останавливать?
Ответ. Существует несколько вариантов. Если у вас есть резервная копия данных
главного сервера на какой-то момент и записано имя файла бинарного журнала и пози-
ция смещения в нем (на основе вывода команды SHOW MASTER STATUS), соответствующие
этому снимку, выполните следующую процедуру:
1. Убедитесь, что подчиненному серверу назначен уникальный идентификатор.
2. Выполните следующие команды на подчиненном сервере, заполнив нужными
значениями каждую из опций:
m y s q l > CHANGE MASTER TO
-> MASTER_HOST=' имя_хоста_главного_сервера',
-> MASTER_USER=' имя_пользователя_репликации*,
-> MASTER_PASSWORD=% пароль_репликацш ',
-> MASTER_LOG_FILE=' имя_файла_записанного_журнала',
-> MASTERJL0G_P0S=no3Han#_B_3a лисаяном^куряале ;
3. Выполните START SLAVE на подчиненном сервере.
Если у вас нет резервной копии данных главного сервера, ниже представлена краткая
процедура ее создания. Все шаги выполняются на главном сервере.
1. Выполните оператор:
m y s q l > FLUSH TABLES WITH READ LOCK;
2. He снимая блокировки, выполните следующую команду (или ее вариацию):
shell> tar zcf /tmp/backup.tar.gz /var/lib/mysql
3. Выполните следующий оператор и запишите его вывод, который понадобится
позже:
mysql> SHOW MASTER STATUS;
4. Снимите блокировку:
m y s q l > UNLOCK TABLES;
В качестве альтернативного варианта можно загрузить SQL-дамп с главного сервера
вместо бинарной копии, как было описано выше. Чтобы это сделать, можно воспользо-
ваться mysqldump —master-date на главном сервере и позже загрузить его на подчинен-
ный. Однако это медленнее, чем в случае бинарной копии.
Независимо от того, какой из двух способов вы выберете, после этого следуйте инст-
рукциям, составленным для случая наличия снимка данных, имени бинарного журнала и
смещения в нем. Вы можете использовать один и тот же снимок для настройки несколь-
394 Глава 5. Репликация в MySQL

ких подчиненных серверов. Если только вы получили снимок данных главного сервера,
вы можете подождать с настройкой подчиненных до тех пор, пока бинарные журналы
главного сервера находятся в целости. Два практических ограничения, накладываемых
на время от выгрузки снимка до настройки подчиненных - это объем дискового про-
странства для хранения растущих файлов бинарного журнала и время, необходимое
подчиненным серверам, чтобы провести репликацию накопившихся изменений.
Вы также можете использовать LOAD DATA FROM MASTER. Это удобный оператор, пе-
реносящий снимок данных на подчиненный сервер и одновременно настраивающий имя
журнала и смещение. В будущем применение оператора LOAD DATA FROM MASTER будет
рекомендовано для первоначальной настройки подчиненного сервера. Помните, однако,
что он работает только с таблицами My ISAM и может долгое время удерживать блокиров-
ку по чтению. Пока еще он не реализован настолько эффективно, как нам бы хотелось.
Если у вас большие таблицы, предпочтительным способом на сегодняшний день являет-
ся создание бинарного снимка данных главного сервера после выполнения оператора
FLUSH TABLES WITH READ LOCK.
Вопрос. Должен ли подчиненный сервер все время быть подключенным к главному?
Ответ. Нет. Подчиненный сервер может оставаться выключенным в течение часов и
даже дней, затем повторно подключиться и захватить накопившиеся изменения. Напри-
мер, вы можете установить между серверами отношение главный/подчиненный по ком-
мутируемой линии, которая работает только эпизодически и в течение кратких периодов
времени. Следствием этого будет то, что не гарантируется синхронность данных между
главным и подчиненным серверами в любой момент времени, если только вы не пре-
дусмотрите каких-то специальных мер. В будущем мы предусмотрим возможность
блокировать главный сервер до тех пор, пока хотя бы один из подчиненных не син-
хронизирован.
Вопрос. Как узнать, когда данные подчиненного сервера сравнивались с данными
главного? Другими словами, как узнать дату последней репликации?
Ответ. Если подчиненный сервер имеет номер версии 4.1.1 или выше, читайте зна-
чение в столбце Seconds_Behind_Master в выводе команды SHOW SLAVE STATUS. Для бо-
лее старых версий подходит следующий способ. Это возможно, только если SHOW
PROCESSLIST на подчиненном сервере показывает, что работает поток SQL (или, для
MySQL 3.23, что работает поток подчиненного сервера), и что он обработал хотя бы од-
но событие, полученное от главного. См. раздел 5.3.
Когда поток SQL обрабатывает событие, прочитанное с главного, он модифицирует
свое собственное время по временной метке события (вот почему TIMESTAMP правильно
реплицируются). В столбце Time вывода команды SHOW PROCESSLIST количество секунд,
отображаемое для потока SQL, представляет собой разность времени между меткой по-
следнего обработанного события и реальным временем машины подчиненного сервера.
Вы можете использовать его для определения даты последнего реплицированного собы-
тия. Следует заметить, что если ваш подчиненный сервер был отключен от главного в
течение одного часа, а затем подключился заново, вы можете немедленно увидеть зна-
чение наподобие 3600 в столбце Time вывода команды SHOW PROCESSLIST. Это объясня-
ется тем, что подчиненный сервер выполняет оператор, которому исполнился один час.
Вопрос. Как заставить главный сервер блокировать изменения до тех пор, пока под-
чиненный не догонит его?
Ответ. Воспользуйтесь следующей процедурой:
5.9. Часто задаваемые вопросы по репликации 395

1. На главном сервере выполните следующие операторы:


mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS;

Запишите имя журнала и смещение, которые покажет команда SHOW. Это - коор-
динаты репликации.
2. На подчиненном сервере выполните следующие операторы, где аргументами
функции MASTER_POS_WAIT() будут координаты репликации, полученные на
предыдущем шаге:
mysql> SELECT MASTER_POS_WAIT('имя_журнала', смещение);
Оператор SELECT заблокирует базу до тех пор, пока подчиненный сервер не дос-
тигнет указанных координат репликации. К этому моменту данные двух серверов
будут синхронизированы, и оператор SELECT возвратит управление.
3. На главном сервере выдайте следующую команду, чтобы снова разрешить ему
принимать запросы на изменение данных от клиентов:
mysql> UNLOCK TABLES;

Вопрос. Что надо знать при настройке двусторонней репликации?


Ответ. Репликация в MySQL на данный момент не поддерживает никакого журнала
блокировок между главным и подчиненным серверами, чтобы гарантировать атомар-
ность распределенного (межсерверного) обновления данных. Другими словами, имеется
возможность для клиента А провести изменения на главном сервере 1, а в это время,
прежде чем изменение распространится на главный сервер 2, клиент В может провести
такое изменение на главном сервере 2, которое заставит изменение от клиента А рабо-
тать иначе, чем оно было сделано на главном сервере 1. Таким образом, когда изменение
от клиента А поступит на главный сервер 2, оно породит таблицу, другую, чем мы име-
ем на главном сервере 1, даже после того, как все изменения от главного сервера 2 рас-
пространятся. Это означает, что нельзя связать два сервера отношением двусторонней
репликации, если только вы не уверены в том, что ваши изменения данных могут проис-
ходить безопасно в любом порядке, либо вы каким-то образом позаботитесь об этих
беспорядочных изменениях в коде клиента.
Кроме того, нужно представлять, что двусторонняя репликация не повысит произво-
дительности значительно (если вообще повысит), поскольку изменения данных будут
связанными. Оба сервера должны будут выполнять одинаковое количество изменений,
которые в обычном случае приходится делать одному. Единственным отличием могло
быть то, что было бы немного меньше соперничества в блокировках, поскольку измене-
ния, порожденные на другом сервере, становились бы последовательными в одном под-
чиненном потоке. Но даже этот минимальный выигрыш мог быть нейтрализован за-
держками в сети.
Вопрос. Как можно использовать репликацию для повышения производительности
системы?
Ответ. Вы должны настроить один сервер как главный и направить все операции за-
писи на него. Затем настройте столько подчиненных серверов, сколько позволяет бюд-
жет и площади помещений, и настройте их так, чтобы операции чтения распределялись
между ними равномерно. Вы также можете запустить подчиненные серверы с опциями
—skip-innodb, —skip-bdb, —low-priority-updates и —delay-key-write=ALL, чтобы
добиться повышения скорости на подчиненных серверах. В этом случае подчиненные
396 Глава 5. Репликация в MySQL

серверы будут использовать нетранзакционные таблицы MylSAM вместо таблиц InnoDB и


BDB, что увеличивает производительность.
Вопрос. Что нужно сделать, чтобы подготовить код клиентских приложений для ис-
пользования репликации, повышающей производительность?
Ответ. Если часть вашего кода, отвечающая за доступ к базе данных, хорошо абстра-
гирована и является модульной, адаптация такого кода к работе со средой репликации
будет легкой и гладкой. Просто измените реализацию доступа к данным таким образом,
чтобы все операции записи обращались к главному серверу, а запросы чтения - как к
главному, так и к подчиненным серверам. Если ваш код не имеет такого уровня абстрак-
ции, настройка системы репликации даст возможность и мотивацию его создать. Начать
стоит с создания библиотеки или модуля оболочки, включающего следующие функции:
• safe_writer_connect()
• safe_reader_connect()
• safe_reader_statement()
• safe_writer_statement()
Префикс saf е_ в именах функций означает, что каждая из них сама заботится об об-
работке ошибочных условий. Вы можете использовать разные имена для функций. Важ-
но лишь обеспечить унифицированный интерфейс подключений для чтения, подключе-
ний для записи, выполнения чтения и выполнения записи. Затем потребуется преобразо-
вать код для использования этой библиотеки. Поначалу это может показаться
болезненным и трудным процессом, однако все усилия окупятся при длительной экс-
плуатации. Все приложения, использующие такой подход, смогут воспользоваться в
полной мере выгодами, приносящими конфигурацией "главный/подчиненный", в том
числе при использовании множества подчиненных серверов. Такой код будет гораздо
проще сопровождать, и добавление опций поиска и устранения неисправностей окажет-
ся тривиальным. То есть вам придется модифицировать одну или две функции, напри-
мер, чтобы добавить регистрацию в журнале времени выполнения каждого оператора,
или для выявления одного из тысяч обрабатываемых запросов, который является причи-
ной ошибок.
Если у вас уже написаны огромные объемы кода, вы можете захотеть автоматизиро-
вать задачу преобразования, используя утилиту replace, поставляемую в стандартном
дистрибутиве MySQL, или же, написав собственный сценарий преобразования. В идеале
ваш код уже использует соглашения последовательного и непротиворечивого стиля про-
граммирования. Если нет, то вам в любом случае лучше переписать его, или, по крайней
мере, пересмотреть и вручную внести изменения, приводящие его в более стройное со-
стояние.
Вопрос. Когда и насколько репликация MySQL повысит производительность системы?
Ответ. Репликация MySQL наиболее выгодна для систем с частым чтением и редкой
записью. Теоретически, используя схему с одним главным и несколькими подчиненны-
ми серверами, вы можете ее масштабировать, добавляя подчиненные серверы до тех
пор, пока или не достигнете ограничения, налагаемого пропускной способностью сети,
или не вырастет до предела загрузка главного сервера, связанная с обновлением данных.
Для того чтобы определить, сколько подчиненных серверов можно добавить до того
момента, когда выигрыш от этого начнет снижаться, и насколько вообще можно повы-
сить производительность системы, вы должны знать шаблоны ваших запросов, и с по-
мощью тестов эмпирически определить соотношение между пропускной способностью
5.9. Часто задаваемые вопросы по репликации 397

операций чтения (чтений в секунду, или maxjreads) и записи (max_writes) на типичном


главном и типичном подчиненном серверах. Приведенный ниже пример показывает до-
вольно упрощенный расчет того, что можно получить от репликации на некоторой гипо-
тетической системе.
Представим, что загрузка системы состоит на 10% из записи и на 90% из чтения, и
мы определили с помощью тестирования, что max_reads равно 1200 - 2 * max__writes.
Другими словами, система может выполнить 1200 чтений в секунду без записи, среднее
время записи вдвое больше, чем среднее время чтения, и зависимость линейная. Пред-
положим, что главный и подчиненные серверы имеют одинаковую мощность, и что мы
имеем один главный сервер и N подчиненных серверов. Тогда мы получаем для каждого
сервера (главного или подчиненного):
reads = 1200 - 2 * writes
reads = 9 * writes / (N + 1) (чтения разделены, но запись выполняется на всех серверах)
9 * writes / (AT + 1) + 2 * writes = 1200
writes = 1200 / (2 + 9/(tf + 1))
Последнее уравнение означает, что максимальное количество чтений для N подчи-
ненных дает максимальную производительность 1200 чтений в минуту и соотношение 9
чтений на одну запись.
Анализ позволяет сделать следующие выводы:
• Если N = 0 (это означает, что репликация не используется), то наша система может
выполнить около 1200 /11 = 109 записей в секунду.
• Если N = 1, мы имеем 184 записи в секунду.
• Если N=8, мы имеем 400 записей в секунду.
• Если N=11, мы имеем 480 записей в секунду.
• В конечном итоге, когда N приближается к бесконечности (а бюджет - к минус
бесконечности), мы можем получить около 600 записей в секунду, повысив про-
изводительность системы в 5,5 раза. Однако уже всего с восемью серверами мы
достигаем роста производительности в 4 раза.
Помните, что эти вычисления предполагают наличие бесконечной пропускной спо-
собности сети и не учитывают ряд других факторов, которые могут ощутимо повлиять
на вашу систему. Во многих случаях вы не сможете выполнить расчеты, подобные при-
веденным выше, которые бы позволили точно предсказать, что случится с вашей систе-
мой, если вы добавите N подчиненных серверов репликации. Однако ответы на следую-
щие вопросы помогут решить, как и насколько репликация может повысить производи-
тельность вашей системы:
• Каково отношение количества операций чтения к операциям записи в вашей сис-
теме?
• Какую загрузку по записи может выдержать один сервер, если уменьшить коли-
чество чтений?
• Сколько подчиненных серверов позволит подключить ваша сеть?
Вопрос. Как использовать репликацию для обеспечения избыточной и высокой дос-
тупности?
Ответ. При имеющихся доступных средствах вы можете настроить главный и под-
чиненный серверы (либо несколько подчиненных), и написать сценарий, который будет
398 Глава 5. Репликация в MySQL

выполнять мониторинг главного сервера, проверяя его готовность. Затем потребуется


проинструктировать ваши приложения и подчиненные серверы о том, как менять глав-
ный сервер в случае его отказа. Ниже представлены некоторые советы.
• Чтобы дать команду подчиненному серверу сменить главныйсервер, используйте
оператор CHANGE MASTER TO.
• Хороший способ информировать приложения о местонахождении главного серве-
ра - это использовать для него динамический адрес DNS. С помощью bind вы
можете применять nsupdate для динамического обновления DNS.
• Вы должны запускать подчиненные серверы с опцией —log-bin и без опции
--log-slave-updates. Таким способом вы обеспечите готовность главного серве-
ра стать подчиненным, как только вы выполните команды STOP SLAVE, RESET
MASTER и CHANGE MASTER TO на других подчиненных серверах. Например, предпо-
ложим, что имеется следующая конфигурация:
WC
\
v
WC >М
/ I \
/ I \
v v v
SI S2 S3
М означает главный (master) сервер, S - подчиненный (slave) сервера, WC - кли-
енты, присылающие запросы на чтение и запись. Клиенты, которым нужен
доступ только по чтению, не представлены, поскольку в переключении они не
нуждаются.
S I , S2 и S3 - это подчиненные серверы, запущенные с опцией — l o g - b i n и без оп-
ции — l o g - s l a v e - u p d a t e s . Поскольку изменения данных, принимаемые подчи-
ненными серверами от главного, не записываются в бинарный журнал, если не
указана опция — l o g - s l a v e - u p d a t e s , бинарный журнал на каждом подчиненном
сервере пуст. Если по какой-то причине М станет недоступным, вы можете вы-
брать один из подчиненных серверов и сделать его главным. Например, выберем
S1. Все WC должны быть перенаправлены на S I , a S2 и S3 должны реплициро-
ваться с S1.
Убедитесь в том, что все подчиненные серверы обработали операторы, находя-
щиеся в их журналах ретрансляции. На каждом подчиненном сервере выполните
команду STOP SLAVE IO_THREAD, затем проверяйте вывод SHOW PROCESSLIST до тех
пор, пока не увидите сообщения "Has read a l l r e l a y l o g s " ("Прочитаны все
журналы ретрансляции"). Когда это произойдет на всех подчиненных серверах,
их можно будет перенастроить на новую конфигурацию. На S1, выбранном для
того, чтобы стать новым главным сервером, выполните STOP SLAVE и RESET
MASTER.
На других подчиненных серверах - S2 и S3 - используйте STOP SLAVE и CHANGE
MASTER TO MASTER_HOST='S1' (где f S l ' представляет реальное имя хоста S1). Чтобы
сменить главный сервер, добавьте всю информацию о том, как подключаться к S1 с
S2 и S3 (имя пользователя, пароль, номер порта). В CHANGE MASTER нет необходимо-
сти указывать имя бинарного журнала S1 и смещение в нем. Мы знаем, что это бу-
5.10. Поиск неисправностей в системе репликации 399

дет первый бинарный журнал с позицией 4, что является значениями по умолчанию


для команды CHANGE MASTER. И, наконец, запустите START SLAVE на S2 и S3.
Затем проинструктируйте все WC, чтобы они направляли свои запросы на S1. С
этого момента все изменения данных, присланные WC на S1, будут записываться
в бинарный журнал на S1, который будет содержать абсолютно все операторы
обновления данных, присланные на S1 с момента выхода из строя М.
В результате получаем следующую конфигурацию:
WC
/
I
WC | М(недоступен)
\I
\ I
VV
SK--S2 S3
I
Когда М будет доступен вновь, вам нужно будет только выполнить на нем коман-
ду CHANGE MASTER, такую же, как вы давали на S2 и S3, таким образом, сделав М
подчиненным для S1 и проведя на нем все изменения, пропущенные с момента
его выхода из строя. Теперь, чтобы его опять сделать главным сервером (напри-
мер, по той причине, что это наиболее мощная машина), повторите описанную
процедуру, как если бы S1 стал недоступен, а М должен стать новым главным
сервером. Не забудьте запустить RESET MASTER на М, прежде чем настраивать S1,
S2 и S3, как его подчиненные серверы. В противном случае можно потерять ста-
рые записи WC до момента его выхода из строя.
В настоящее время мы работаем над системой интеграции автоматического выбора
главного сервера в MySQL, но пока она не готова, вам придется создавать собственные
средства мониторинга.

5.10. Поиск неисправностей в системе


репликации
Если вы следовали инструкциям, но ваша настройка репликации не работает, сначала
проверьте следующие моменты:
• Проверьте сообщения в журнале ошибок. Многие теряют время, не делая этого.
• Выполняется ли бинарная регистрация на главном сервере? Проверьте с помощью
команды SHOW MASTER STATUS. Если да, столбец Position будет иметь ненулевое
значение. Если нет, убедитесь, что вы запускаете главный сервер с опциями
—log-bin и —server-id.
• Запущена ли репликация на подчиненном сервере? Используйте SHOW SLAVE STATUS
для проверки того, что переменные Slave_IO_Running и Slave_SQL_Running имеют
значения Yes. Если нет, проверьте, с какими опциями запускается подчиненный
сервер.
• Если подчиненный сервер запущен, установил ли он связь с главным сервером?
Воспользуйтесь SHOW PROCESSLIST, чтобы найти потоки репликации ввода-вывода
400 Глава 5. Репликация в MySQL

и SQL и проверить значение их столбца State. См. раздел 5.3. Если значение
State для потока ввода-вывода равно Connecting to master (Подключение к
главному серверу), проверьте привилегии пользователя репликации на главном
сервере, его имя хоста, ваши настройки DNS, работает ли главный сервер в дан-
ный момент и доступен ли он с подчиненного сервера.
• Если подчиненный сервер работал ранее, а теперь остановлен, причина обычно
состоит в том, что некий оператор, успешно выполненный на главном сервере, не
прошел на подчиненном. Это никогда не должно случаться, если у вас был кор-
ректный первоначальный снимок данных главного сервера, и данные подчинен-
ного не модифицировались вне его потоков репликации. Если это так, то, вероят-
но, это ошибка, либо вы столкнулись с одним из известных ограничений реплика-
ции, описанных в разделе 5.7. Если это ошибка, в разделе 5.11 можно найти
инструкции о том, как сообщать об ошибках.
• Если оператор, выполненный успешно на главном сервере, отвергнут подчинен-
ным, и нет реальной возможности осуществить полную ресинхронизацию (то
есть, удалить базу данных подчиненного и скопировать новый снимок с главно-
го), попробуйте выполнить следующие действия:
1. Определите, чем отличается таблица на подчиненном сервере от той же табли-
цы на главном. Попытайтесь разобраться, как это получилось. Затем приведи-
те таблицу на подчиненном сервере в состояние, эквивалентное ее состоянию
на главном сервере, и выполните START SLAVE.
2. Если предыдущий шаг не работает или невозможен, попробуйте разобраться,
нельзя ли провести обновление вручную (при необходимости), а затем
проигнорировать следующий оператор с главного сервера.
3. Если вы решите, что следующий оператор с главного сервера можно пропус-
тить, выполните следующие операторы:
mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = л;
raysql> START SLAVE;
Значение л должно быть равно 1, если следующий оператор с главного сервера
не использует AUTO_INCREMENT или LAST_INSERT_ID(). В противном случае
значение должно быть равно 2. Причина указания значения 2 для операторов,
ИСПОЛЬЗУЮЩИХ AUTO_INCREMENT ИЛИ LAST_INSERT_ID ( ) , СОСТОИТ В ТОМ, ЧТО ОНИ
берут два события в бинарном журнале главного сервера.
4. Если вы уверены, что подчиненный сервер стартовал, будучи идеально син-
хронизированным с главным, и никто не вносил изменений в данные подчи-
ненного сервера вне системы репликации, значит, предположительно, расхож-
дения объясняются ошибкой кода сервера. Если вы работаете с самой послед-
ней версией, сообщите нам о проблеме. Если у вас более старая версия
MySQL, попробуйте ее обновить.

5.11. Сообщения об ошибках репликации


Если вы убедились, что не было никаких пользовательских ошибок, а репликация
либо не работает, либо функционирует нестабильно, значит, наступило время сообщать
об ошибке. Мы хотели бы получать как можно больше информации от вас, чтобы разо-
5.11. Сообщения об ошибках репликации 401

браться в причинах проблемы. Потратьте некоторое время и усилия, чтобы подготовить


хороший отчет об ошибке.
Если у вас есть воспроизводимый тестовый случай, демонстрирующий ошибку, вне-
сите его в нашу базу ошибок на http://bugs.mysql.com/. Если ваша проблема носит
фантомный характер (то есть ее невозможно воспроизвести по желанию), выполните
следующую процедуру:
1. Убедитесь, что не было никаких пользовательских ошибок. Например, если вы
обновляете данные на подчиненном сервере непосредственно, вне системы реп-
ликации, данные рассинхронизируются, и вы можете получить ошибки наруше-
ния уникальности при обновлении данных. В этом случае потоки подчиненного
сервера, обслуживающие репликацию, останавливаются и ожидают, когда вы
вручную приведете данные в синхронное состояние. Это не проблема реплика-
ции. Это проблема внешнего влияния, которое приводит к сбою репликации.
2. Запустите подчиненный сервер с опциями —log-slave-updates и —log-bin. Это
вынудит его записывать все операторы, которые приходят от главного сервера, в
собственный бинарный журнал.
3. Сохраните все симптомы проблем перед сбросом состояния репликации. Если у
нас нет информации, или она имеет беглый, неполный характер, это затрудняет
или делает невозможным разобраться в причинах проблемы.
Свидетельства проблемы, которые вы должны собрать:
• Все бинарные журналы главного сервера.
• Все бинарные журналы подчиненного сервера.
• Вывод SHOW MASTER STATUS с главного сервера, полученный в момент обнару-
жения проблемы.
• Вывод SHOW SLAVE STATUS с подчиненного сервера, полученный в момент об-
наружения проблемы.
• Журналы ошибок с главного и подчиненного серверов.
4. Воспользуйтесь mysqlbinlog для проверки бинарных журналов. Следующая ко-
манда должна помочь в поиске проблемного запроса, например:
shell> mysqlbinlog -j no3nu,MR_B_slave_status \
/путь/к/журнал_из_з1ауе_зЬаЬиз | head
Как только вы соберете все свидетельства фантомной проблемы, попробуйте ее
изолировать в отдельном тестовом случае. Затем внесите проблему в нашу базу ошибок
на h t t p : //bugs .mysql. com/, сопроводив ее как можно более подробной информацией.
6

Оптимизация MySQL

О птимизация - это комплексная задача, поскольку в конечном итоге она требует


понимания всей системы, в которой выполняется. Несмотря на то что можно вы-
полнить некоторую локальную оптимизацию, обладая минимальными знаниями систе-
мы или приложения, однако, чем более оптимальная система необходима, тем больше о
ней следует знать.
В этой главе объясняются различные способы оптимизации MySQL и приводятся не-
которые характерные примеры. Помните, однако, что всегда есть дополнительные пути
сделать вашу систему еще быстрее, хотя это и потребует приложить дополнительные
усилия.

6.1. Обзор оптимизации


Самый важный фактор в достижении высокой производительности системы - это ее
базовая конструкция. Вы также должны представлять, какие типы задач будет выпол-
нять ваша система, и где у нее могут быть узкие места.
Основные узкие места системы таковы:
• Поиск информации на диске. Диску требуется определенное время, чтобы найти
какую-то часть данных. У современных дисков среднее время доступа обычно
меньше 10 миллисекунд, то есть теоретически можно говорить о 100 операциях
поиска в секунду. Этот показатель у новых дисков постепенно растет, но его
чрезвычайно трудно оптимизировать для доступа к отдельной таблице. Способ
оптимизировать время доступа диска заключается в распределении данных на бо-
лее чем одном диске.
• Чтение и запись на диск. Когда головки диска находится в правильной позиции,
необходимо прочесть данные. Современные диски обеспечивают пропускную
способность данных при чтении и записи, как минимум, в пределах 10-20 Мбайт
в секунду. Это легче оптимизировать, чем время поиска, потому что можно орга-
низовать параллельное чтение с нескольких дисков.
• Циклы центрального процессора. Когда данные поступают в основную память
(или уже находятся там), их нужно обработать, чтобы получить какой-то резуль-
тат. Маленькие таблицы, объем которых сравним с объемом памяти - самый об-
щий ограничивающий фактор. Но при маленьких таблицах обычно скорость не
является проблемой.
6.1. Обзор оптимизации 403

• Пропускная способность памяти. Когда центральный процессор нуждается в


большем количестве данных, чем помещается в его кэш, пропускная способность
памяти становится узким местом. Это не слишком существенное узкое место для
большинства систем, но одно из тех, о которых нужно помнить.

6.1.1. Ограничения и компромиссы конструкции MySQL


При использовании механизма хранения My ISAM MySQL использует чрезвычайно бы-
струю систему блокировки таблиц, которая позволяет параллельно выполнять множест-
во чтений или одну запись. Самая большая проблема с этим механизмом хранения про-
является тогда, когда идет устойчивый поток смешанных операторов обновления и мед-
ленных запросов к одной и той же таблице. Если это становится проблемой для
определенных таблиц, вы можете выбрать для них другие типы (см. главу 8).
MySQL может работать как с транзакционными, так и с нетранзакционными табли-
цами. Чтобы работать гладко с нетранзакционными таблицами (которые невозможно
откатить, если что-то пошло не так), MySQL следует определенным правилам:
• Все столбцы имеют значения по умолчанию.
• Если вы вставляете "неверное" значение в столбец, такое как слишком больше
число в числовой столбец, MySQL устанавливает для него "наилучшее возможное
значение" вместо того, чтобы выдать ошибку. Для числовых столбцов таким зна-
чением является 0, наименьшее возможное, или наибольшее возможное значение.
Для строк - это либо пустая строка, либо самая длинная возможная строка, кото-
рая помещается в столбец.
• Все вычисляемые выражения возвращают значение, которое можно использовать,
вместо выдачи сигнала об ошибочном условии. Например, 1/0 возвращает NULL.
Следствием этих правил является то, что вы не должны использовать MySQL для
проверки содержимого столбцов. Вместо этого вы должны проверять значения в прило-
жении прежде, чем помещать их в базу данных.

6.1.2. Проектирование переносимых приложений


Поскольку все серверы SQL реализуют разные части стандарта SQL, написание пе-
реносимого приложения требует определенных усилий. Очень легко добиться перено-
симости для простейших запросов и вставок, но становится намного сложнее, если вам
требуется использовать больше возможностей. Если вам нужно приложение, которое
работает быстро на разных базах данных, это становится еще труднее!
Чтобы обеспечить переносимость сложного приложения, потребуется определить, с
какими серверами SQL оно должно работать, а затем выяснить, какие средства эти сер-
веры поддерживают.
Все системы управления базами данных (СУБД) имеют определенные слабые места.
То есть они имеют определенные компромиссы в конструкции, которые приводят к раз-
личному поведению в сходных ситуациях.
С помощью MySQL-программы crash-me можно найти функции, типы и ограниче-
ния, которые должны учитываться при выборе сервера баз данных, crash-me не проверя-
ет все возможные средства, но она достаточно исчерпывающая, поскольку выполняет
около 450 тестов.
404 Глава 6. Оптимизация MySQL

Примером типа информации, которую может предоставить crash-me, может быть то,
что вы не должны использовать имена столбцов длиннее 18 символов, если собираетесь
взаимодействовать с Informix или DB2.
Программа crash-me и тесты производительности MySQL мало зависят от конкрет-
ной СУБД. Взглянув на то, как они написаны, вы можете получить представление о том,
как ваши собственные программы сделать независимыми от СУБД. Эти программы на-
ходятся в каталоге sql-bench исходного дистрибутива MySQL. Они реализованы на
языке Perl и используют интерфейс баз данных DBI. Применение DBI само по себе ре-
шает проблемы переносимости, поскольку он предлагает независимые от СУБД методы
доступа.
За результатами crash-me обращайтесь по адресу http://dev.mysql.com/tech-
resources/crash-me.php. Результаты тестов производительности можно увидеть по ад-
ресу http://dev.mysql.com/tech-resources/benchmarks/.
Если вы стремитесь к независимости от СУБД, вы должны получить хорошее пред-
ставление об узких местах каждого из серверов SQL. Например, MySQL очень быстро
работает при извлечении и обновлении записей в таблицах My ISAM, но имеет проблемы
при смешанном применении медленного чтения и записи на одной и той же таблице. С
другой стороны, Oracle имеет большие проблемы при попытке получить доступ к стро-
кам, которые только что обновлены (пока они не сброшены на диск). Транзакционные
базы данных вообще не очень хороши для генерации отчетных таблиц из таблиц журна-
лов, поскольку в этом случае блокировка строк практически бесполезна.
Чтобы сделать ваши приложения действительно независимыми от СУБД, вы долж-
ны определить легко расширяемый интерфейс, посредством которого можно манипули-
ровать данными. Так как язык C++ доступен в большинстве систем, имеет смысл ис-
пользовать интерфейс доступа к базам данных, основанный на классах C++.
Если вы применяете средства, специфичные для конкретной СУБД (такие как опера-
тор REPLACE, который есть в MySQL), вы должны реализовать такие же средства для
других серверов SQL, закодировав их альтернативным методом. Несмотря на то что он
может оказаться медленнее, такой подход позволит выполнять те же задачи на других
серверах.
В MySQL вы можете использовать синтаксис /*! */ для добавления к запросам
ключевых слов, специфичных для MySQL. Код внутри /* */ рассматривается как ком-
ментарий (и игнорируется) большинством других SQL-серверов.
Если высокая производительность более важна, чем точность данных, как это бывает
в некоторых Web-приложениях, появляется возможность создать уровень приложения,
который кэширует результаты для повышения производительности. Позволяя старым
результатам запросов исчезать со временем, вы можете поддерживать кэш в достаточно
актуальном состоянии. Это является хорошим способом справиться с пиковыми нагруз-
ками, в случае которых можно динамически увеличивать размер кэша и устанавливать
таймаут "устаревания" данных в нем большим до тех пор, пока нагрузка не вернется в
норму.
В этом случае информация о создании таблицы должна включать информацию о на-
чальном размере кэша и периоде его обновления.
Альтернативой кэшу уровня приложений является использование кэша запросов
MySQL. При включенном кэше запросов сервер сам принимает решения о том, когда
результаты запросов могут быть использованы повторно. Это позволяет упростить при-
ложения. См. 4.10.
6.1. Обзор оптимизации 405

6.1.3. Для чего мы использовали MySQL


В настоящем разделе описываются ранние приложения MySQL.
Во время первоначального создания MySQL его средства разрабатывались под нуж-
ды нашего крупнейшего заказчика, который управлял хранилищем данных для группы
больших розничных торговых компаний Швеции.
Мы получали еженедельные итоги по всем транзакциям, касающимся бонус-карт, и
должны были предоставлять владельцам магазинов полезную информацию, призванную
помочь им оценить, насколько проводимые ими рекламные кампании влияли на их соб-
ственных клиентов.
Объем данных был достаточно велик (около 7 миллионов суммарных транзакций в
месяц), и мы располагали данными за 4-10 лет, которые необходимо было предостав-
лять пользователям. Мы получали еженедельные запросы от наших клиентов, которые
хотели иметь прямой доступ к новым отчетам по этим данным.
Мы решили упомянутую проблему, поместив всю информацию за месяц в сжатые
таблицы транзакций. У нас был набор простых макросов, которые генерировали итого-
вые таблицы, группируя данные по разным критериям (продуктовая группа, идентифи-
катор клиента и так далее) из таблиц, в которых хранилась информация о торговых тран-
закциях. Отчеты представляли собой Web-страницы, динамически сгенерированные не-
большим сценарием на Perl. Этот сценарий анализировал Web-страницу, выполнял SQL-
операторы, находящиеся на ней, и помещал на их место результаты. Мы бы использова-
ли вместо этого РНР или modperl, однако они были на то время недоступны.
Для представления данных в графической форме мы написали простой инструмент
на языке С, который мог обрабатывать результаты SQL-запросов и генерировать GIF-
изображения на базе их результатов. Этот инструмент также динамически вызывался из
Perl-сценария, который обрабатывал Web-страницы.
В большинстве случаев новый отчет мог быть создан простым копированием суще-
ствующего сценария с модификацией SQL-запроса в нем. В некоторых случаях нам
нужно было добавить больше столбцов к итоговой таблице, или сгенерировать новую,
но это также было достаточно просто, потому что мы сохраняли все таблицы с торговы-
ми транзакциями на диске (использовалось около 50 Гбайт под таблицу транзакций и
200 Гбайт - под другие пользовательские данные).
Мы также предоставляли заказчикам непосредственный доступ к итоговым таблицам
через ODBC, чтобы опытные пользователи могли самостоятельно экспериментировать с
данными.
Система работала хорошо, и у нас не было проблем с управлением данными на срав-
нительно скромном оборудовании - Sun Ultra SPARCstation (2 х 200 Мгц). Со временем
система была перенесена под Linux.

6.1.4. Набор тестов производительности MySQL


В этом разделе должно находиться техническое описание набора тестов производи-
тельности MySQL (benchmark suite) и crash-me, однако само описание еще не готово. В
настоящее время вы можете получить представление о тестах производительности, оз-
накомившись с кодом и результатами тестов в каталоге sql-bench любого дистрибутива
MySQL.
Набор тестов производительности предназначен для того, чтобы продемонстриро-
вать, какие операции данная реализация SQL выполняет хорошо или плохо.
406 Глава 6. Оптимизация MySQL

Помните, что все эти тесты однопоточные, поэтому замеряют минимальное время
выполнения операций. В будущем мы планируем добавить многопоточные тесты. Для
использования набора тестов производительности необходимо удовлетворить следую-
щим требованиям:
• Тесты производительности предоставляются исходным дистрибутивом MySQL.
Вы можете либо загрузить такой дистрибутив с http://dev.mysql.com/downloads/,
либо использовать текущее дерево разработки исходных текстов (см. раздел 2.3.3).
• Тестовые сценарии написаны на Perl и используют модуль Perl DBI для доступа к
серверам баз данных, полому DBI должен быть установлен. Вам также понадо-
бятся специфичные для сервера драйверы DBD - по одному для каждого сервера,
который необходимо протестировать. Например, чтобы протестировать MySQL,
PostgreSQL и DB2, вы должны иметь установленные модули DBD: :mysql, DBD: :Pg
и DBD:: DB2. См. раздел 2.7.
После того, как вы получите исходный дистрибутив MySQL, вы найдете набор тес-
тов производительности в его подкаталоге sql-bench. Чтобы запустить их, выполните
сборку MySQL, затем перейдите в подкаталог sql-bench и выполните сценарий
run-all-tests:
shell> cd sql-bench
shell> perl run-all-tests —server-имя^сервера
имя_сервера - это один из поддерживаемых серверов. Для получения списка опций и
поддерживаемых серверов воспользуйтесь командой:
shell> perl run-all-tests —help
Сценарий crash-me также находится в каталоге sql-bench. Этот сценарий пытается
определить, какие средства база данных поддерживает и какие у нее возможности и ог-
раничения для выполнения запросов. В частности, сценарий определяет:
• Какие поддерживаются типы столбцов.
• Сколько поддерживается индексов.
• Какие поддерживаются функции.
• Насколько большим может быть запрос.
• Насколько большими могут быть столбцы типа VARCHAR.
Вы можете найти результаты crash-me для многих различных серверов баз данных
по адресу http: //dev.mysql ..com/tech-resources/crash-me.php.
Более подробная информация о результатах тестов производительности доступна по
адресу http://dev.mysql.com/tech-resources/benchmarks.

6.1.5. Использование собственных тестов


производительности
Для того чтобы найти узкие места в своих приложениях и базах данных, их потребу-
ется обстоятельно протестировать на предмет производительности. Найдя одно из них (и
заменив на "модуль-заглушку"), вы можете легко идентифицировать следующее. Даже
если общая производительность вашего приложения приемлема, вы должны, по крайней
мере, составить план узких мест и решить, как избавляться от них, когда понадобится
искать резервы производительности.
6.2. Оптимизация операторов SELECT и других запросов 407

В качестве примера переносимых тестовых программ ознакомьтесь с набором тестов


производительности MySQL (см. раздел 6.1.4). Вы можете взять любую из программ
этого набора и модифицировать по собственному усмотрению. Сделав это, вы можете
попробовать различные решения вашей проблемы и определить, какое из них самое бы-
строе.
Другой бесплатный набор тестов производительности, Open Source Database
Benchmark, можно найти на сайте http://osdb.sourceforge.net/.
Очень часто проблемы проявляются тогда, когда система сильно загружена. У нас
было много заказчиков, которые связывались с нами, когда во время эксплуатации про-
тестированных систем сталкивались с проблемами высокой нагрузки. В большинстве
случаев причина проблем производительности своими корнями уходит в базовую конст-
рукцию СУБД (например, сканирование таблиц работает неважно при высоких нагруз-
ках), либо связана с проблемами операционной системы или библиотек. Как правило,
такие проблемы намного проще решать, когда система еще не запущена в производст-
венную эксплуатацию.
Во избежание подобных проблем, вы должны приложить некоторые усилия, чтобы
протестировать общую производительность приложения под максимально возможной
нагрузкой. Для этого можете воспользоваться инструмент Super Smack, который досту-
пен по адресу http://jeremy.zawodny.com/mysql/super-sraack/. Упомянутый инстру-
мент может поставить систему "на колени", поэтому используйте его только в системах,
предназначенных для разработчиков.

6.2. Оптимизация операторов SELECT


и других запросов
Первое, что затрагивает все операторы: чем более сложна ваша настройка системы
доступа, тем большую нагрузку вы получите.
Использование более простых прав доступа, которые устанавливаются с помощью
оператора GRANT, позволяет MySQL снизить нагрузку, связанную с их проверкой. На-
пример, если вы не определяете никаких привилегий уровня таблицы или уровня столб-
ца, то серверу не придется обращаться к таблицам tables_priv и columns_priv. Анало-
гично, если ни для каких пользовательских учетных записей не задаются ограничения на
доступ к ресурсам, серверу не придется вести учет этих ресурсов. Если у вас очень вы-
сокий объем запросов, может быть, стоит потратить время на упрощение структуры
привилегий, дабы снизить нагрузку сервера, связанную с их проверкой.
Если проблема связана с некоторыми специфичными выражениями и функциями
MySQL, можете с помощью функции BENCHMARK () в клиентской программе выполнить
замеры времени. Синтаксис это функции таков: BENCHMARK {количество__циклов, выражение).
Например:

| BENCHMARK(1000000,1+1) |
+ +
I 0|
+ +
1 row in s e t (0.32 sec)
408 Глава 6. Оптимизация MySQL

Эти результаты были получены в системе с процессором Pentium II400 Мгц. Они по-
казывают, что MySQL может выполнить в этой системе 1 000 000 простых выражений
суммирования за 0,32 секунды.
Все функции MySQL должны быть очень хорошо оптимизированы, однако сущест-
вуют и некоторые исключения. BENCHMARK () - отличный инструмент для определения,
связана ли проблема с запросами.

6.2.1. Синтаксис оператора EXPLAIN


(получение информации о SELECT)
EXPLAIN имя_таблицы

или
EXPLAIN SELECT onu,MM_select

Оператор EXPLAIN, как и его синоним DESCRIBE, может использоваться для получения
информации о том, как MySQL будет выполнять оператор SELECT:
• Синтаксис EXPLAIN имя_таблицы - это синоним для DESCRIBE имя_таблицы или
SHOW COLUMNS FROM имя_таблицы.
• Когда вы предваряете оператор SELECT ключевым словом EXPLAIN, MySQL объяс-
няет, как он будет обрабатывать SELECT, предоставляя информацию о том, как
объединяются таблицы и в каком порядке.
Этот раздел посвящен второму применению EXPLAIN.
С помощью EXPLAIN вы можете увидеть, когда к таблицам нужно добавить индексы,
чтобы получить более быстрый SELECT, который будет использовать индексы для поиска
записей.
Вы должны периодически запускать ANALYZE TABLE для обновления статистики таб-
лиц, такой как распределение значений ключей, которое может повлиять на принятие
решений оптимизатором.
Вы также можете увидеть, в правильном ли порядке оптимизатор выполняет соеди-
нение таблиц. Чтобы заставить оптимизатор использовать порядок соединения таблиц в
соответствии с тем, который указан в операторе SELECT, этот оператор должен начинать-
ся С SELECT STRAIGHT_JOIN вместо просто SELECT.
EXPLAIN возвращает строку информации для каждой таблицы, используемой в опера-
торе SELECT. Таблицы перечисляются в том порядке, в котором MySQL читает их при
обработке запроса. MySQL разбирает все соединения, используя однопроходный много-
связный (single-sweep multi-join) метод. Это означает, что MySQL читает строку из пер-
вой таблицы, затем находит соответствующую строку во второй таблице, затем в треть-
ей и так далее. Когда все таблицы обработаны, он выводит выбранные столбцы и вы-
полняет обратный обход в списке таблиц до тех пор, пока не найдет таблицу, в которой
есть еще подходящие строки. Следующая строка читается из этой таблицы, и процесс
продолжается со следующей таблицей.
В MySQL 4.1 формат вывода EXPLAIN был изменен, чтобы лучше работать с такими
конструкциями, как UNION, подзапросами и производными таблицами. Наиболее значи-
тельным нововведением является добавление новых столбцов: i d и s e l e c t _ t y p e . Вы не
увидите этих столбцов, если работаете с серверами более старыми, чем MySQL 4.1.
6.2. Оптимизация операторов SELECT и других запросов 409

Каждая строка вывода EXPLAIN представляет информацию об одной таблице и состо-


ит из следующих столбцов:
• id. Идентификатор SELECT. Это порядковый номер оператора SELECT в запросе.
• s e l e c t _ t y p e . Тип оператора SELECT, который может быть одним из следующих:
• SIMPLE. Простой оператор SELECT (не использующий UNION или SUBQUERY).
• PRIMARY. Внешний оператор SELECT.
• UNION. Второй или последний оператор SELECT в UNION.
• DEPENDENT UNION. Второй или последний оператор SELECT в UNION, зависящий
от внешнего подзапроса.
• SUBQUERY. Первый оператор SELECT в подзапросе.
• DEPENDENT SUBQUERY. Первый оператор SELECT в подзапросе, зависящий от
внешнего подзапроса.
• DERIVED. Оператор SELECT на порожденной таблице (подзапрос в конструкции
FROM).
• t a b l e . Таблица, на которую ссылается строка вывода.
• type. Тип соединения. Различные типы соединений перечислены ниже, от лучше-
го к худшему:
• system. Таблица имеет только одну строку (= системная таблица). Это специ-
альный случай типа соединения const.
• const. Таблица имеет только максимум одну подходящую строку, которая бу-
дет прочитана в начале выполнения запроса. Поскольку строка только одна,
значения ее столбцов могут быть приняты оптимизатором для дальнейшей об-
работки в качестве констант. Таблицы const очень быстрые, поскольку считы-
ваются только однажды.
const применяются, когда вы сравниваете все части индекса PRIMARY KEY или
UNIQUE с константными значениями. В следующих запросах таблица
имя_ та блицы может быть использована как const-таблица:
SELECT * FROM имя_таблицы WHERE первичный_ключ=1 ;
SELECT * FROM имя_таблицы
WHERE первичный_ключ_часть1=1 AND первичный_ключ_часть2=2;
• eq_ref. Одна строка данной таблицы будет прочитана для каждой комбинации
строк предыдущих таблиц. Это лучший из возможных тип соединения, если не
считать const. Он применяется, когда все части индекса используются соеди-
нением, а индекс является PRIMARY KEY или UNIQUE.
e q r e f может быть использован для индексированных столбцов, которые
сравниваются с помощью операции =. Сравниваемое значение может быть
константой или выражением, которое использует столбцы из таблиц, прочи-
танных перед данной таблицей.
В следующих примерах MySQL может использовать соединение eq_ref для
обработки таблицы таблица_ссылок:
SELECT * FROM таблица_ссылок,другая_таблица
WHERE таблица ссылок.ключевой столбец^ другая_таблица.столбец;
410 Глава 6. Оптимизация MySQL

SELECT * FROM таблица_ссылок, другая__таблица


WHERE та блица_ ссылок. ключев ой_столбец_ часть 1 =другая^ та блица. столбец
AND таблица_ссылок. ключевой__столбец_часть2=1;
• ref. Все строки с подходящим значением индекса будут прочитаны из табли-
цы для каждой комбинации строк предыдущих таблиц, ref применяется, если
соединения использует только левую часть ключа, или же ключ не является
индексом PRIMARY KEY или UNIQUE (другими словами, если соединение не мо-
жет извлечь единственную строку на основании значения ключа). Если ис-
пользуемый ключ соответствует только нескольким строкам, это хороший тип
соединения.
ref может быть использован для индексированных столбцов, которые
сравниваются с помощью операции =.
В следующих примерах MySQL может использовать соединение ref для обра-
ботки таблицы таблица_ссылок:
SELECT * FROM таблица_ссылок WHERE ключевой_столбец=выражение;
SELECT * FROM таблица_ссылок,другая_таблица
WHERE та блица_ссылок. ключев ой_столбец=другая^ та блица. столбец;
SELECT * FROM таблица^ссылок, другая_таблица
WHERE та блица_ ссылок. ключев ой_столбец_ ча сть 1 =другая_ та блица. столбец
AND таблица_ссылок. ключевой_столбец_часть2=1;
• r e f o r n u l l . Тип соединения, подобный ref, но с тем отличием, что MySQL
будет выполнять дополнительный поиск строк, содержащих значения NULL.
Оптимизация этого типа соединений является новой в MySQL 4.1.1, и в основ-
ном применяется для разрешения подзапросов.
В следующих примерах MySQL может использовать соединение r e f o r n u l l
для обработки таблицы таблица_ссылок:
SELECT * FROM таблица_ссылок
WHERE ключевой_столбец=выражение OR ключевой_столбец IS NULL;
См. раздел 6.2.6.
• indexmerge. Этот тип означает, что применяется оптимизация соединения ин-
дексов (index Merge). В данном случае ключевой столбец содержит список
используемых индексов, a key_len — список самых длинных частей ключа для
используемых индексов. Более подробную информацию можно найти в разде-
ле 6.2.5.
• uniquesubquery. Этот тип заменяет ref в некоторых подзапросах IN следую-
щего вида:
значение IN (SELECT первичный_ключ FROM таблица WHERE выражение)
uniquesubquery - это просто функция поиска по индексу, которая для боль-
шей эффективности полностью заменяет подзапрос.
• index_subquery. Этот тип соединения похож на unique_subquery. Он заменяет
подзапросы IN, но работает с неуникальными индексами в подзапросах сле-
дующего вида:
значение IN (SELECT ключевой^столбец FROM таблица WHERE выражение)
6.2. Оптимизация операторов SELECT и других запросов 411

• range. Извлекаются строки только из заданного диапазона с использованием


индекса для их выбора. Столбец key показывает, какой индекс используется.
k e y l e n содержит самую длинную используемую часть индекса. Столбец ref
для этого типа будет NULL.
range может применяться, когда ключевой столбец сравнивается с константой,
используя любую из операций: =, о , >, >=, <, <=, IS NULL, <=>, BETWEEN или IN:
SELECT * FROM имя_таблицы
WHERE ключевой^столбец = 10;
SELECT * FROM имя_таблицы
WHERE ключевой_столбец BETWEEN 10 and 2 0 ;
SELECT * FROM имя_таблицы
WHERE ключевой^столбец IN ( 1 0 , 2 0 , 3 0 ) ;
SELECT * FROM имя_таблицы
WHERE часть_ключа1= 10 AND часть_ключа2 IN ( 1 0 , 2 0 , 3 0 ) ;
• index. Этот тип соединения - такой же, как ALL, с тем отличием, что сканиру-
ется только дерево индекса. Обычно это быстрее, чем ALL, поскольку файл ин-
декса меньше файла данных. MySQL может использовать этот тип соедине-
ния, когда запрос включает столбцы, являющиеся частью одного индекса.
• ALL. Полное сканирование таблицы будет выполняться для каждой комбина-
ции строк предыдущих таблиц. Обычно это не особенно хорошо, если данная
таблица - первая, не помеченная как const, и обычно очень плохо во всех ос-
тальных случаях. Как правило, вы можете избежать ALL, добавив индексы, ко-
торые позволят извлекать строки из таблицы на основании константных зна-
чений или значений столбцов из предыдущих таблиц.
• p o s s i b l e k e y s . Столбец p o s s i b l e k e y s указывает, какие индексы может исполь-
зовать MySQL для поиска строк в таблице. Имейте в виду, что этот столбец пол-
ностью независим от порядка таблиц, выведенных EXPLAIN. Это означает, что не-
которые ключи из possible_keys могут быть не используемыми на практике при
сгенерированном порядке следования таблиц.
Если эта столбец содержит NULL, значит, подходящих индексов нет. В этом случае
вы можете увеличить производительность запроса, пересмотрев аргументы кон-
струкции WHERE, чтобы найти там столбец или столбцы, которые стоило бы про-
индексировать. Если это так, создайте соответствующий индекс и снова проверьте
запрос с помощью EXPLAIN. Для просмотра индексов таблицы служит оператор
SHOW INDEX FROM имя_таблицы.
• key. Столбец key показывает ключ (индекс), который оптимизатор MySQL в
действительности решает использовать. Эта столбец содержит NULL, если никакой
индекс не выбран. Чтобы заставить MySQL использовать или игнорировать ин-
декс из перечисленных в списке possible_keys, указывайте в запросах конструк-
ции FORCE INDEX, USE INDEX ИЛИ IGNORE INDEX.
Для таблиц My I SAM и BDB запуск ANALYZE TABLE поможет оптимизатору выбрать
наиболее подходящие индексы. Для таблиц MylSAM запуск myisamchk —analyze
сделает то же самое. См. раздел 4.6.2.
• key-len. Столбец key-len показывает длину ключа, который MySQL решает ис-
пользовать. Эта столбец содержит NULL, когда столбец key содержит NULL. Следу-
412 Глава 6. Оптимизация MySQL

ет заметить, что значение key-len позволяет определить, какую часть составного


ключа в действительности использует MySQL.
• ref. Столбец ref показывает, какие столбцы или константы применяются с key
для выбора строк из таблицы.
• rows. Столбец rows показывает количество строк, которое, как считает MySQL,
должно быть рассмотрено для выполнения запроса.
• Extra. Эта столбец содержит дополнительную информацию о том, как MySQL
разбирает запрос. Далее приведен список значений с объяснениями, которые мо-
жет принимать этот столбец:
• Distinct. MySQL прекратит поиск дополнительных строк для текущей ком-
бинации строк после того, как найдет первую строку.
• Not exists. MySQL готов выполнить оптимизацию LEFT JOIN для запроса и
не будет проверять больше строк в таблице для предыдущей комбинации
строк после того, как найдет первую подходящую по критерию LEFT JOIN.
Ниже приведен пример запроса, который может быть оптимизирован таким
образом:
SELECT * FROM tl LEFT JOIN t2 ON tl.id=t2.id
WHERE t2.id IS NULL;
Предположим, что столбец t 2 . i d объявлен как NOT NULL. В этом случае
MySQL просканирует t l и поищет в t2 строки, используя значение t l . id. Ес-
ли соответствующие строки будут найдены в t2, он знает, что t 2 . i d никогда
не может быть NULL, и не станет просматривать остальные строки t2, которые
имеют то же значение id. Другими словами, для каждой строки в t l MySQL
должен выполнить поиск только одной строки в t2, независимо от того, сколь-
ко там подходящих строк на самом деле.
• range checked for each record (index map: #). MySQL не нашел подходя-
щего индекса для использования. Вместо этого, для каждой комбинации из
предыдущей таблицы он выполнит проверку с целью определения того, какой
индекс применить (если есть), и использует его для извлечения строк из таб-
лицы. Это не очень быстро, но все же быстрее, чем выполнять соединение во-
обще без индексов.
• Using filesort. MySQL нуждается в дополнительном проходе для извлечения
строк в отсортированном порядке. Сортировка выполняется проходом по всем
строкам в соответствии с типом соединения и сохранением ключа сортировки
и указателя на строку для всех строк, удовлетворяющих условию WHERE. Клю-
чи затем сортируются и строки извлекаются в отсортированном порядке.
• Using index. Информация столбцов извлекается из таблицы с использованием
только той информации, которая хранится в дереве индекса, без необходимо-
сти доступа к самой строке. Эта стратегия применима только в случае, когда
запрос использует только столбцы, являющиеся частью ключа одного индекса.
• Using temporary. Для разбора запроса MySQL понадобится создать времен-
ную таблицу, чтобы сохранить результат. Обычно такое случается, когда за-
прос содержит конструкции GROUP BY и ORDER BY, которые по-разному пере-
числяют столбцы.
6.2. Оптимизация операторов SELECT и других запросов 413

• Using where. Конструкция WHERE будет использоваться для ограничения строк,


сочетающихся со следующей таблицей или подлежащих отправке клиенту.
Если явно не указать, что нужно извлекать или проверять все строки таблицы,
можно получить неверный результат запроса, если значение Extra не будет
Using where, а тип соединения - ALL или index.
Если вы хотите, чтобы запрос выполнялся настолько быстро, насколько это воз-
можно, нужно добиться, чтобы столбец Extra принимал значения Using f i l e s o r t
и Using temporary.
Хорошую оценку конкретного соединения можно получить, если взять произведение
значений столбца rows в выводе EXPLAIN. Это будет приблизительное число строк, которые
MySQL должен проверить, чтобы выполнить запрос. Если же вы ограничиваете свои запро-
сы системной переменной raax_join_size, это произведение также используется для опреде-
ления того, какие многотабличные операторы SELECT нужно выполнять. См. раздел 6.5.2.
В следующем примере показано, как можно прогрессивно оптимизировать многотаб-
личное соединение с использованием информации, предоставляемой EXPLAIN.
Предположим, что имеется оператор SELECT, приведенный ниже, и вы собираетесь
исследовать его с помощью EXPLAIN:
EXPLAIN SELECT tt.TicketNumber, tt.Timeln,
tt.ProjectReference, tt.EstimatedShipDate,
tt.ActualShipDate, t t . C l i e n t I D ,
tt.ServiceCodes, tt.RepetitivelD,
tt.CurrentProcess, tt.CurrentDPPerson,
tt.RecordVolume, tt.DPPrinted, et.COUNTRY,
et_l.COUNTRY, do.CUSTNAME
FROM t t , e t , et AS e t _ l , do
WHERE tt.SubmitTime IS NULL
AND tt.ActualPC = et.EMPLOYID
AND tt.AssignedPC = et_l.EMPLOYID
AND t t . C l i e n t I D = do.CUSTNMBR;
Для целей этого примера сделаем следующие предположения:
• Сравниваемые столбцы объявлены следующим образом:
Таблица Столбец Тип столбца
It ActualPC CHAR(IO)
tt AssignedPC CHAR(IO)
tt ClientID CHAR(IO)
et EMPLOYID CHAR(15)
do CUSTNMBR CHAR(15)
• Таблицы имеют с л е д у ю щ и е индексы:
Таблица Индекс
tt ActualPC
tt AssignedPC
tt ClientID
et EMPLOYID (первичный ключ)
do CUSTNMBR (первичный ключ)
• Значения tt. ActualPC распределены неравномерно.
414 Глава 6. Оптимизация MySQL

Изначально, до того, как предприняты попытки оптимизации, оператор EXPLAIN вы-


дает следующую информацию:
table type possible_keys keykey key__len
key ref
len ref rows
rows Extra
et ALL PRIMARY NULL NULL NULL 74
do ALL PRIMARY NULL NULL NULL 2135
et_l ALL PRIMARY NULL NULL NULL 74
tt ALL AssignedPC, NULL NULL NULL 3872
ClientID,
ActualPC
range checked for each record (key map: 35)
Поскольку значение type равно ALL для всех таблиц, это означает, что MySQL гене-
рирует декартово произведение всех таблиц, то есть все возможные комбинации строк.
Это может потребовать достаточно длительного времени, поскольку должно быть про-
верено количество строк, равное произведению количеств строк во всех участвующих
таблицах. В данном случае получается 74 * 2135 * 74 * 3871 = 45 268 558 720 строк. Ес-
ли таблицы будут больше, можно себе представить, сколько времени это займет.
Одна проблема здесь заключается в том, что MySQL может использовать индексы на
столбцах более эффективно, если они объявлены одинаково. (Для таблиц ISAM индексы
вообще не могут быть использованы, если только столбцы не объявлены одинаково.) В
этом контексте VARCHAR и CHAR - это одно и то же, если только они не имеют разную
длину. Поскольку столбец tt.ActualPC объявлен как CHAR(IO), a et.EMPLOYID - как
CHAR (15), налицо несоответствие длин.
Для исправления этого расхождения между столбцами с помощью ALTER TABLE уве-
личьте длину столбца Actual PC с 10 символов до 15:
mysql> ALTER TABLE t t MODIFY ActualPC VARCHAR(15);
Теперь и tt.ActualPC, и et.EMPLOYID имеют тип VARCHAR(15). Запустив оператор
EXPLAIN снова, получаем результат:
table type possible_keys key key_len ref rows Extra
tt ALL AssignedPC, NULL NULL NULL 3872 Using
ClientID, where
ActualPC
do ALL PRIMARY NULL NULL NULL 2135
ange checked f o r each r e c o r d (key map: 1)
et_l ALL PRIMARY NULL NULL NULL 74
range checked for each record (key map: 1)
et eq_ref PRIMARY PRIMARY 15 tt.ActualPC 1
Пока не блестяще, но уже значительно лучше: произведение значений столбца rows
меньше в 74 раза. Эта версия запроса выполняется за несколько секунд.
Второе изменение структуры может быть сделано с целью исключения несоответ-
ствия длин столбцов для сравнений t t . AssignedPC = e t _ l .EMPLOYID и t t . C l i e n t ID =
do.CUSTNMBR:
mysql> ALTER TABLE t t MODIFY AssignedPC VARCHAR(15),
-> MODIFY C l i e n t I D VARCHAR(15);
Теперь EXPLAIN выдает следующую информацию:
table type possible_keys key key len ref rows Extra
et ALL PRIMARY NULL NULL NULL 74
6.2. Оптимизация операторов SELECT и других запросов 415

tt ref AssignedPC, ActualPC 15 et .EMPLOYID 52 Using


ClientID, where
ActualPC
et 1 eq ref PRIMARY PRIMARY 15 tt .AssignedPC 1
do eq ref PRIMARY PRIMARY 15 tt .ClientID 1
Это практически идеально.
Осталась еще одна проблема, которая заключается в том, что по умолчанию MySQL
предполагает, что значения столбца tt.ActualPC распределены равномерно, но для таб-
лицы t t на самом деле это не так. К счастью, легко заставить MySQL проанализировать
реальное распределение значений:
mysql> ANALYZE TABLE tt;
Теперь соединение просто блестяще и EXPLAIN выдает такой результат:
table type possible_keys key key_len reJ rows Extra
tt ALL AssignedPC NULL NULL NULL 3872 Using
ClientID, where
ActualPC
et eq ref PRIMARY PRIMARY 15 tt..ActualPC 1
et 1 eq_ref PRIMARY PRIMARY 15 tt..AssignedPC 1
do eq ref PRIMARY PRIMARY 15 tt,.ClientID 1
Имейте в виду, что значение в столбце rows в выводе EXPLAIN является квалифициро-
ванным предположением оптимизатора MySQL. Вы должны проверить, близки ли эти
цифры к реальным. Если нет, можно получить более высокую производительность, ис-
пользуя STRAIGHT_JOIN в операторе SELECT, и попробовать перечислить таблицы в кон-
струкции FROM в другом порядке.

6.2.2. Ожидаемая производительность запросов


В большинстве случаев можно оценить производительность, посчитав обращения к
диску. Для маленьких таблиц, как правило, вы можете найти строку за одно обращение к
диску (поскольку, вероятно, индекс кэширован). Для таблиц побольше вы можете оце-
нить, что при использовании индексов в виде бинарных деревьев понадобится следую-
щее количество операций доступа к диску:
l o g {количество_строк) I l o g {длина_индексного_блока / 3 * 2 / [длина_индекса
+ длина_указателя__данных)) +1
В MySQL индексный блок обычно имеет размер 1024 байта, а указатель на данные -
как правило, 4 байта. Для таблицы в 500 000 строк с длиной ключа индекса в 3 байта
(среднее целое), формула дает log (500,000) /log (1024/3*2/ (3+4)) + 1 = 4 обращения
к диску.
Упомянутый индекс потребует для своего хранения около 500000 * 7 * 3/2 = 5,2 Мбайт
(предполагая, что типичное наполнение индексного буфера составляет 2/3), поэтому
вероятно, большая часть индекса будет находиться в памяти и понадобится только один
или два вызова, чтобы прочитать данные при поиске строки.
Для записи, однако, понадобится четыре обращения к диску, чтобы найти место, куда
поместить новый ключ индекса, и обычно два обращения, чтобы обновить индекс и за-
писать строку.
Имейте в виду, что предыдущие расчеты вовсе не означают, что производительность
вашего приложения будет медленно снижаться по закону log N. До тех пор, пока все кэ-
416 Глава 6. Оптимизация MySQL

шируется операционной системой или SQL-сервером, с ростом таблиц эти вещи будут
замедляться только в малой степени. После того, как объем данных станет слишком
большим, чтобы поддаваться кэшированию, все станет работать значительно медленнее,
до тех пор, пока ваше приложение ограничивается только количеством обращений к
диску (которое растет по закону log N). Чтобы избежать этого, с ростом объема данных
увеличивайте размер кэша ключей. Для таблиц MylSAM размер кэша ключей управляется
системной переменной keyjouf f er_size. См. раздел 6.5.2.

6.2.3. Скорость выполнения запросов SELECT


Обычно, когда вы хотите, чтобы медленный запрос SELECT.. .WHERE работал быстрее,
первое, что потребуется сделать - это проверить, нельзя ли добавить индекс. Все ссылки
между разными таблицами обычно должны использовать индексы. Вы можете потом с
помощью EXPLAIN проверить, какие индексы использует SELECT. См. разделы 6.4.5 и 6.2.1.
Ниже представлены некоторые общие советы по повышению скорости запросов к
таблицам My ISAM:
• Чтобы помочь оптимизатору MySQL выполнять запросы быстрее, запустите
ANALYZE TABLE или myisamchk —analyze для таблицы после того, как в нее будут
загружены данные. Это обновит те части индексов, которые хранят информацию
о среднем количестве строк с одинаковыми значениями ключа (для уникальных
индексов это всегда 1). MySQL будет использовать это для принятия решения, ка-
кой индекс выбрать при соединении таблиц на базе неконстантных выражений.
Вы можете увидеть результат проведенного анализа таблиц с помощью SHOW
INDEX FROM имя_таблицы, просмотрев там значение Cardinality, myisamchk
—description --verbose показывает информацию о распределении индекса.
• Чтобы отсортировать индекс и данные на основе индекса, используйте myisamchk
--sort-index —sort-records=l (если вы хотите сортировать по индексу 1). Это
хороший способ ускорить запросы, если имеется уникальный индекс, из которого
вы хотите извлекать все записи в порядке, соответствующем индексу. Заметьте,
что в первый раз, когда вы сортируете большую таблицу подобным способом, это
может занять длительное время.

6.2.4. Как MySQL оптимизирует конструкцию WHERE


В этом разделе обсуждаются оптимизации, которые можно сделать для обработки
конструкций WHERE. В примере рассматривается оператор SELECT, но то же самое касает-
ся и конструкции WHERE в операторах DELETE и UPDATE.
Помните, что работа над оптимизатором MySQL продолжается, поэтому настоящий
раздел далеко не полон. MySQL выполняет разнообразную оптимизацию, и не вся она
здесь документирована.
Некоторые виды оптимизации, выполняемые MySQL, перечислены ниже.
• Удаление лишних скобок:
((a AND b) AND с OR ( ( ( a AND b) AND (с AND d ) ) ) )
-> (a AND b AND c) OR (a AND b AND с AND d)
• Подстановка констант:
(a<b AND b=c) AND a=5
-> b>5 AND b=c AND a=5
6.2. Оптимизация операторов SELECT и других запросов 417

• Удаление константных условий (необходимо из-за подстановки констант):


(В>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6)
-> В=5 OR В=б

• Константные выражения в индексах вычисляются только один раз.


• COUNT (*) по одной таблице, без условия WHERE, выбирается непосредственно из
информации о таблице My ISAM и HEAP. Это также делается для любых выражений
NOT NULL, когда применяется только с одной таблицей.
• Раннее обнаружение неверных константных выражений. MySQL быстро опреде-
ляет, что определенный оператор SELECT невозможен и не возвращает строк.
• HAVING объединяется с WHERE, если не используется GROUP BY или групповые
функции (COUNT (), MIN () и так далее).
• Для каждой таблицы в соединении конструируется упрощенное условие WHERE
для быстрого вычисления и пропуска лишних строк на как можно более раннем
этапе.
• Все константные таблицы читаются первыми, до остальных таблиц в запросе.
Константными считаются следующие таблицы:
• Пустые таблицы или таблицы с одной строкой.
• Таблицы, используемые в конструкции WHERE на индексе PRIMARY KEY или
UNIQUE, где все части индекса сравниваются с константными выражениями и
объявлены как NOT NULL.
Все следующие таблицы используются как константные:
SELECT * FROM t WHERE первичный_ключ=1;
SELECT * FROM t l , t 2
WHERE tl.первичный_ключ =1 AND t2.первичный_ключ=Ь1.id;
• Лучшая комбинация соединения таблиц находится после выбора из всех возмож-
ных. Если все столбцы в конструкциях ORDER BY и GROUP BY поступают из одной
таблицы, этой таблице отдается предпочтение в качестве первой в соединении.
• Если есть конструкция ORDER BY и другая конструкция GROUP BY, или же если
ORDER BY или GROUP BY содержат столбцы из таблиц, отличных от первой таблицы
в объединенном запросе, создается временная таблица.
• Если вы используете SQL_SMALL_RESULT, MySQL применяет временные таблицы,
размещенные в памяти.
• Опрашивается каждый индекс таблицы, и лучший из них используется, если
только оптимизатор не считает, что полное сканирование таблицы более эффек-
тивно. Ранее сканирование таблицы применялось на основании того, что индекс
покрывал более 30% таблицы. Теперь оптимизатор стал более сложным, и осно-
вывает свою оценку на добавочных факторах, таких как размер таблицы, количе-
ство строк, размер блока ввода-вывода. То есть фиксированный процент не опре-
деляет более выбора между использованием индекса и полным сканированием.
• В некоторых случаях MySQL может читать строки из индекса, даже не загляды-
вая в файл данных. Если все столбцы, используемые в индексе, являются число-
выми, для разбора запроса используется только дерево индекса.
418 Глава 6. Оптимизация MySQL

• Прежде чем каждая запись будет выведена, записи, которые не удовлетворяют


условию HAVING, пропускаются.
Вот некоторые примеры запросов, выполняющихся очень быстро:
SELECT COUNT (*) FROM имя__таблицы;
SELECT MIN (часть_ключа1), MAX (часть_ключа1) FROM имя_таблицы;
SELECT МАХ{часть__ключа2) FROM t b l имя__таблицы
WHERE часть_ключа2=константа;
SELECT . . . FROM имя_таблицы
ORDER BY часть_ключа1, часть_ключа2, . . . LIMIT 1 0 ;
SELECT . . . FROM имя__таблицы
ORDER BY часть_ключа1 DESC, часть_ключа2 DESC, . . . LIMIT 1 0 ;

Следующие запросы разбираются только на основании дерева индекса, предполагая,


что индексные столбцы являются числовыми:
SELECT часть_ключа1, часть__ключа2 FROM имя_таблицы
WHERE часть_ключа1-значение;
SELECT COUNT(*) FROM имя_таблицы
WHERE часть_ключа1=значение! AND часть_ключа2~значение2;
SELECT часть_ключа2 FROM имя_таблицы GROUP BY часть__ключа1;

Приведенные ниже запросы используют индексацию для извлечения строк в отсор-


тированном порядке без дополнительного прохода:
SELECT . . . FROM имя_таблицы
ORDER BY часть_ключа1, часть_ключа2, ... ;
SELECT . . . FROM имя_таблицы
ORDER BY часть_ключа1 DESC, часть_ключа2 DESC, ... ;

6.2.5. Как MySQL оптимизирует выражения OR


Метод соединения индексов (Index Merge) применяется для извлечения строк с не-
сколькими сканированиями ref, ref_or_null или range и слияния результатов в один.
Этот метод применяется, когда условие выбора в таблице является дизъюнкцией условий,
для которых ref, ref_or_null или range могут использоваться с различными ключами.
Этот тип оптимизации, связанный с соединением, является новым в MySQL 5.0.0; он
представляет ощутимые изменения в поведении, связанном с применением индексов,
поскольку старое правило заключалось в том, что сервер был в состоянии использовать
максимум один индекс для каждой упоминаемой в запросе таблицы.
В выводе команды EXPLAIN этот метод появляется как index_merge в столбце type. В
этом случае столбец key содержит список применяемых индексов, a key_len - список
самых длинных частей ключа этих индексов.
Вот примеры:
SELECT * FROM имя_таблицы WHERE часть_ключа1 = 10 OR часть_ключа2 = 20;
SELECT * FROM имя_таблицы
WHERE {часть_ключа! = 10 OR часть__ключа2 = 20) AND неключевая_часть = 30;
SELECT * FROM t l , t 2
WHERE ( t l . к л ю ч 1 IN ( 1 , 2 ) OR t l . к л ю ч 2 LIKE 'значение*')
AND Ь2.ключ1=Ь1.столбец;
SELECT * FROM t l , t 2
WHERE tl.ключ1=1
AND ( t 2 . k e y l = t l . с т о л б е ц OR t 2 . k e y 2 = t l . д р у г о й столбец);
6.2. Оптимизация операторов SELECT и других запросов 419

6.2.6. Как MySQL оптимизирует IS NULL


MySQL может выполнять такую же оптимизацию выражения имя_столбца IS NULL,
как он делает с имя__столбца = константное_значение. Например, MySQL может ис-
пользовать индексы и диапазоны для поиска NULL с IS NULL.
SELECT * FROM имя_таблицы WHERE ключевой_столбец I S NULL;
SELECT * FROM имя_таблицы WHERE ключевой_столбец <=> NULL;
SELECT * FROM имя_таблицы
WHERE ключевой_столбец= константа 1 OR ключевой__столбец=константа2
OR ключевой_столбец IS NULL;
Если конструкция WHERE содержит условие имя_столбца IS NULL для столбца, объяв-
ленного как NOT NULL, это выражение будет исключено оптимизатором. Однако такая
оптимизация не производится в случае, когда эта столбец все-таки может иметь значе-
ние NULL, например, если он поступает из таблицы, находящейся справа от LEFT JOIN.
MySQL 4.1.1 и выше может дополнительно оптимизировать комбинацию
имя_столбца = выражение AND имя_столбца IS NULL - форму, часто встречающуюся в
подзапросах. EXPLAIN отобразит ref_or_null, когда такая оптимизация выполняется.
Оптимизация может обрабатывать одно условие IS NULL для любой части ключа.
Вот некоторые примеры оптимизированных запросов с предположением, что суще-
ствует индекс на столбцах а и b таблицы t2:
SELECT * FROM t l WHERE t l . a = e x p r OR t l . a I S NULL;
SELECT * FROM t l , t 2 WHERE t l . a = t 2 . a OR t 2 . a I S NULL;
SELECT * FROM t l , t 2
WHERE ( t l . a = t 2 . a OR t 2 . a I S NULL) AND t 2 . b = t l . b ;
SELECT * FROM t l , t 2
WHERE t l . a = t 2 . a AND ( t 2 . b = t l . b OR t 2 . b I S N U L L ) ;
SELECT * FROM t l , t 2
WHERE ( t l . a = t 2 . a AND t 2 . a I S NULL AND . . . )
OR ( t l . a = t 2 . a AND t 2 . a I S NULL AND . . . ) ;
ref_or_null работает, вначале выполняя чтение по указанному ключу, а затем осу-
ществляя отдельный поиск строк со значением ключа NULL.
Учтите, что оптимизатор может справиться только с одним уровнем IS NULL. В сле-
дующем запросе MySQL применяет поиск ключа только в выражении ( t l . a = t 2 . a AND
t2. a IS NULL) и не сможет использовать ключевую часть на Ь:
SELECT * FROM t l , t 2
WHERE ( t l . a = t 2 . a AND t 2 . a I S NULL)
OR ( t l . b = t 2 . b AND t 2 . b I S NULL);

6.2.7. Как MySQL оптимизирует DISTINCT


DISTINCT в комбинации с ORDER BY во многих случаях нуждается в создании времен-
ной таблицы.
Помните, что поскольку DISTINCT может использовать GROUP BY, вы должны пред-
ставлять, как MySQL работает со столбцами в конструкциях ORDER BY или HAVING, кото-
рые не являются частью списка выбираемых столбцов.
MySQL расширяет применение GROUP BY так, что вы можете использовать столбцы и
вычисления в списке столбцов SELECT, которые не появляются в конструкции GROUP BY.
420 Глава 6. Оптимизация MySQL

Это стоит за любым возможным значением для данной группы. Вы можете применять
это для достижения более высокой производительности, избегая сортировки и группи-
рования по ненужным элементам. Например, вам не нужно группировать по
customer.name в следующем запросе:
mysql> SELECT o r d e r . c u s t i d , customer.name, MAX(payments)
-> FROM order,customer
-> WHERE o r d e r . c u s t i d = customer.custid
-> GROUP BY order.custid;
В стандартном SQL вам пришлось бы добавлять customer.name в конструкцию GROUP
BY. В MySQL это имя излишне, если только вы не работаете в режиме ANSI.
Не применяйте это средство, если столбцы, которые вы пропускаете в GROUP BY, не
являются уникальными в группе. Вы получите непредсказуемые результаты.
В некоторых случаях вы можете использовать MIN () и МАХ () для получения специфи-
ческого значения столбца, даже если оно не уникально. Следующее выражение возвра-
щает значение column из строки, содержащей самое маленькое значение столбца sort:
SUBSTR(MIN(CONCAT(RPAD(sort,6,' '),column)),7)
При комбинации LIMIT колмчество_строк с DISTINCT сервер MySQL остановится,
как только найдет количество_строк уникальных строк.
Если вы не извлекаете столбцы из всех таблиц, участвующих в запросе, MySQL ос-
танавливает сканирование неиспользуемых таблиц, как только найдет первое попадание.
В следующем примере, предполагая, что t l используется перед t2 (это можно проверить
с помощью EXPLAIN), MySQL останавливает чтение из t2 (для любой отдельной строки
из t l ) , как только будет найдена первая строка t2:
SELECT DISTINCT t l . a FROM t l , t 2 where t l . a = t 2 . a ;

6.2.8. Как MySQL оптимизирует LEFT JOIN и RIGHT JOIN


LEFT JOIN В условие_соединения реализовано в MySQL следующим образом:
• Таблица В устанавливается как зависимая от таблицы А и всех таблиц, от кото-
рых зависит А.
• Таблица А устанавливается как зависимая от всех таблиц (кроме В), которые ис-
пользуются В УСЛОВИИ LEFT JOIN.
• Условие LEFT JOIN используется для принятия решений о том, как извлекать
строки из таблицы В. (Другими словами, никакие условия в конструкции WHERE не
применяются).
• Выполняется вся стандартная оптимизация соединений, за исключением того, что
таблица читается всегда после всех таблиц, от которых она зависит. Если имеются
циклические зависимости, MySQL выдает ошибку.
• Выполняется вся стандартная оптимизация WHERE.
• Если в А существует строка, соответствующая условию WHERE, но нет строк в В,
соответствующих условию ON, генерируются дополнительные строки В со всеми
столбцами, установленными в NULL.
• Если вы используете LEFT JOIN, чтобы найти строки, которые не существуют в
некоторой таблице, и указано условие имя_столбца IS NULL в части WHERE, где
6.2. Оптимизация операторов SELECT и других запросов 421

имя_столбца - это столбец, объявленный как NOT NULL, MySQL останавливает по-
иск строк (для отдельной комбинации ключей) после того, как найдет одну стро-
ку, соответствующую условию LEFT JOIN.
RIGHT JOIN реализован аналогично, со сменой ролей связанных таблиц.
Оптимизатор соединений вычисляет порядок, в котором должны объединяться таб-
лицы. Порядок чтения таблиц обусловлен LEFT JOIN, и STRAIGHT_JOIN помогает оптими-
затору выполнять его работу намного быстрее, поскольку ему не приходится сравнивать
различные перестановки таблиц. Помните, что это означает, что если выполняется за-
прос показанного ниже типа, MySQL выполнит полное сканирование Ь, потому что LEFT
JOIN указывает читать ее перед d:
SELECT *
FROM a,b LEFT JOIN с ON (c.key=a.key) LEFT JOIN d ON (d.key=a.key)
WHERE b.key=d.key;
Чтобы исправить это, в данном случае нужно переписать запрос следующим обра-
зом:
SELECT *
FROM b , a LEFT JOIN с ON ( с . k e y = a . k e y ) LEFT JOIN d ON ( d . k e y = a . k e y )
WHERE b . k e y = d . k e y ;

Начиная с версии 4.0.14, MySQL выполняет следующую оптимизацию LEFT JOIN:


если условие WHERE всегда возвращает false для сгенерированной строки NULL, LEFT
JOIN заменяется обычным соединением.
Например, если столбец t2.columnl будет равен NULL, то в следующем запросе кон-
струкция WHERE будет возвращать false:
SELECT * FROM t l LEFT JOIN t2 ON (columnl) WHERE t2.column2=5;
Поэтому его можно преобразовать к нормальному соединению:
SELECT * FROM t l , t 2 WHERE t2.column2=5 AND tl.columnl=t2.columnl;
Такой запрос может быть выполнен быстрее, так как MySQL теперь может использо-
вать таблицу t2 перед таблицей t l . Чтобы жестко задать порядок таблиц, применяйте
STRAIGHT_JOIN.

6.2.9. Как MySQL оптимизирует ORDER BY


В некоторых случаях MySQL может использовать индексы, чтобы удовлетворить тре-
бованиям конструкций ORDER BY и GROUP BY, не выполняя дополнительную сортировку.
Индекс может использоваться даже в тех случаях, когда ORDER BY не полностью со-
ответствует ключу индекса до тех пор, пока все неиспользуемые части индекса и все
дополнительные столбцы ORDER BY являются константами в конструкции WHERE.
Следующие запросы будут использовать индекс для разрешения частей ORDER BY и
GROUP BY:
SELECT * FROM t l ORDER BY часть_ключа!,часть_ключа2, ... ;
SELECT * FROM t l WHERE часть_ключа1=константа ORDER BY часть_ключа2;
SELECT * FROM t l WHERE часть_ключа1=константа GROUP BY часть_ключа2;
SELECT * FROM t l ORDER BY часть_ключа1 DESC, часть_ключа2 DESC;
SELECT * FROM tl
WHERE часть ключа2=1 ORDER BY часть ключа! DESC, часть ключа2 DESC;
422 Глава 6. Оптимизация MySQL

В некоторых случаях MySQL не может использовать индексы для разрешения кон-


струкций ORDER BY и GROUP BY несмотря на то, что он по-прежнему применяет индексы
для поиска строк, удовлетворяющих условию WHERE. Эти случаи включают следующие:
• Используется ORDER BY на разных ключах:
SELECT * FROM t l ORDER BY ключ1, ключ2;
• Используется ORDER BY на непоследовательных частях ключа:
SELECT * FROM t l WHERE часть_ключа2=константа ORDER BY часть_ключа2;
• Используется смесь из ASC и DESC:
SELECT * FROM t l ORDER BY часть_ключа1 DESC, часть_ключа2 ASC;
• Ключ, применяемый для извлечения строк, не совпадает с тем, который использу-
ется В ORDER BY:
SELECT * FROM t l WHERE ключ2=константa ORDER BY ключ1;
• Связывается множество таблиц, и столбцы в ORDER BY - не все из первой некон-
стантной таблицы, которая используется для извлечения строк. (Это первая таб-
лица в списке, выводимом EXPLAIN, которая не имеет типа соединения const.)
• Применяются разные выражения ORDER BY и GROUP BY.
• Тип используемого индекса таблицы не сохраняет строки в определенном поряд-
ке. Например, это касается HASH-индексов для НЕАР-таблиц.
В тех случаях, когда MySQL должен сортировать результаты, он применяет следую-
щий алгоритм:
1. Читает все строки по ключу или путем сканирования таблицы. Строки, не соот-
ветствующие условию WHERE, пропускаются.
2. Сохраняет ключ сортировки в буфере. Размер буфера задается системной пере-
менной sort_buffer_size.
3. Когда буфер наполняется, запускает qsort (quicksort) на нем и сохраняет результат
во временном файле. Сохраняет указатель на отсортированный блок. (Если все
строки попадают в буфер, временный файл не создается.)
4. Повторяет предыдущие шаги до тех пор, пока все строки не будут прочитаны.
5. Выполняет множественное слияние вплоть до MERGEBUFF (7) областей в один блок
в другом временном файле. Повторяет до тех пор, пока все блоки из первого фай-
ла не оказываются во втором файле.
6. Повторяет последующие шаги до тех пор, пока не останется блоков меньше, чем
MERGEBUFF2 (15).
7. В последней операции множественного слияния в результирующий файл записы-
вается только указатель на строку (последняя часть ключа сортировки).
8. Читает строки в порядке сортировки, используя указатели на строки в результи-
рующем файле. Чтобы оптимизировать это, выполняется чтение в большой блок
указателей строк, его сортировка и затем использование этого блока для чтения
строк в сортированном виде в буфер строк. Размер этого буфера задается систем-
ной переменной read_rnd_buffer_size. Код, реализующий данный шаг, находит-
ся в исходном файле sql/records. ее.
6.2. Оптимизация операторов SELECT и других запросов 423

Может ли MySQL использовать индексы для выполнения запроса, легко проверить с


помощью EXPLAIN SELECT.. .ORDER BY. Если вы видите Using f i l e s o r t в столбце Extra,
это значит, что использовать индексы MySQL не может. См. раздел 6.2.1.
Если вы хотите увеличить скорость ORDER BY, сначала посмотрите, можно ли заста-
вить MySQL использовать индексы вместо дополнительной фазы сортировки. Если
нельзя, можно попробовать следующие стратегии:
• Увеличить размер переменной sort_buf fer_size.
• Увеличить размер переменной read_rnd_buf fer_size.
• Изменить tmpdir, чтобы он указывал на каталог в файловой системе с большим
объемом свободного пространства. Если вы работаете с версией MySQL 4.1 или
более новой, эта опция допускает указание нескольких путей, используемых в
циклическом порядке. Пути должный быть разделены символом ' : ' в Unix или ' ; '
в Windows, NetWare и OS/2. Вы можете использовать это средство для распреде-
ления нагрузки по нескольким каталогам.
На заметку!
:;!; Пути должны указывать на каталоги, расположенные на разных физических дисках, а не разде-
Л л ах одного и того же диска.

По умолчанию MySQL сортирует запросы GROUP BY столбец!, столбец2,... так,


как если бы в запросе было бы также указано ORDER BY столбец1, столбец2, . . . Если
конструкция ORDER BY явно включена в запрос и содержит тот же список столбцов,
MySQL во время оптимизации убирает его, безо всякого ущерба для скорости, даже не-
смотря на то, что происходит сортировка. Если запрос включает в себя GROUP BY, но вы
хотите избежать избыточной нагрузки за счет сортировки результатов, то сортировку
можно подавить, добавив ORDER BY NULL, например:
INSERT INTO foo
SELECT a, COUNT(*) FROM bar GROUP BY a ORDER BY NULL;

6.2.10. Как MySQL оптимизирует LIMIT


В некоторых случаях MySQL обрабатывает запросы по-разному, когда применяется
LIMIT количество_строк и не используется HAVING:
• Если вы выбираете только несколько строк с LIMIT, MySQL использует индексы в
некоторых случаях, когда обычно более предпочтительно полное сканирование
таблицы.
• Если вы применяете LIMIT количество_строк с ORDER BY, MySQL прекращает
сортировку сразу, как только найдет первые количество_строк строк вместо того,
чтобы сортировать всю таблицу.
• При комбинации LIMIT количество_строк с DISTINCT, MySQL останавливается,
как только найдет количество_строк уникальных строк.
• В некоторых случаях конструкция GROUP BY может быть разрешена чтением клю-
ча по порядку (или выполнением сортировки по ключу) с последующим вычисле-
нием итогов до тех пор, пока ключ не изменится. В этом случае LIMIT количест-
во_строк не будет вычислять никаких ненужных значений GROUP BY.
424 Глава 6. Оптимизация MySQL

• Как только MySQL отправляет заказанное число строк клиенту, он прерывает вы-
полнение запроса, если только вы не используете SQL_CALC_FOUND_ROWS.
• LIMIT 0 всегда быстро возвращает пустой набор. Это полезно для проверки за-
проса или для получения типов результирующих столбцов.
• Когда сервер использует временные таблицы для обработки запроса, LIMIT коли-
чество_строк применяется для вычисления необходимого объема дискового про-
странства.

6.2.11. Как избежать сканирования таблиц


EXPLAIN показывает значение ALL в столбце type, когда MySQL осуществляет полное
сканирование таблицы при выполнении запроса. Обычно это случается при следующих
условиях:
• Таблица настолько мала, что быстрее выполнить полное сканирование, чем поиск
по ключу. Это обычный случай для таблиц, в которых меньше 10 строк и неболь-
шая длина строки.
• Не указаны ограничения в конструкциях ON или WHERE для индексированных
столбцов.
• Индексированные столбцы сравниваются с константными значениями, и MySQL
(на основе индексного дерева) вычисляет, что константа покрывает значительную
часть таблицы и поэтому полное сканирование должно быть быстрее. См. раздел
6.2.4.
• Вы используете ключ с малым количеством возможных значений (значению клю-
ча соответствует много строк) среди других столбцов. В этом случае MySQL
предполагает, что применение ключа приведет к большому количеству поисков
по ключу и поэтому сканирование таблицы будет выполнено быстрее.
Для небольших таблиц сканирование часто подходит. Для больших таблиц попро-
буйте следующую технику минимизации ошибочного выбора оптимизатором полного
сканирования:
• Используйте ANALYZE TABLE имя_таблицы с целью обновления информации о рас-
пределении значений ключей индексов для сканируемых таблиц.
• Используйте FORCE INDEX для сканируемых таблиц, чтобы указать MySQL, что
сканирование таблицы обойдется дороже, чем доступ с использованием индекса.
SELECT * FROM t l , t2 FORCE INDEX (индекс_для_столбца)
WHERE 11. имя_столбца^2 . имя_стрлбца;
• Запускайте mysqld с опцией —max-seeks-for-key=1000 либо применяйте SET
max_seeks_for_key=1000, чтобы указать оптимизатору, что никакие сканирования
ключей не потребуют более 1000 чтений. См. раздел 4.2.3.

6.2.12. Скорость выполнения запросов INSERT


Время на вставку записи определяется следующими факторами, где числа показыва-
ют предположительные пропорции:
• Подключение: (3)
• Отправка запроса серверу: (2)
6.2. Оптимизация операторов SELECT и других запросов 425

• Разбор запроса: (2)


• Вставка записи: (1 х размер записи)
• Вставка индекса: (1 х количество записей)
• Закрытие: (1)
Здесь не принимаются во внимание затраты на открытие таблиц, которые выполня-
ются однажды для каждого параллельного выполняющегося запроса.
Размер таблицы замедляет вставку индексов по закону log N, предполагая, что речь
идет об индексах на основе бинарных деревьев.
Для ускорения вставки можно применить следующие методы:
• Если вы вставляете много строк с одного клиента в одно и то же время, применяйте
операторы INSERT с множеством списков VALUES, чтобы добавлять сразу несколько
строк. Это значительно быстрее (в некоторых случаях во много раз), чем использо-
вать отдельные однострочные операторы INSERT. Если вы добавляете данные в
непустую таблицу, можете настроить переменную bulk_insert_buffer_size, чтобы
это делалось еще быстрее (см. раздел 4.2.3).
• Если вы вставляете множество строк с разных клиентов, то можете получить бо-
лее высокую скорость, применяя оператор INSERT DELAYED.
• В таблицы My ISAM можно вставлять строки одновременно с выполнением запро-
сов SELECT, если только в таблице нет удаленных строк.
• При загрузке таблицы из текстового файла применяйте LOAD DATA INFILE. Обыч-
но это работает в 20 раз быстрее, чем при использовании множества операторов
INSERT.

• Потратив незначительные дополнительные усилия, можно добиться того, что LOAD


DATA INFILE будет работать даже еще быстрее. Для этого выполните следующую
процедуру:
1. Необязательно создайте таблицу с помощью CREATE TABLE.
2. Выполните оператор FLUSH TABLES или команду mysqladmin flush-tables.
3. Используйте myisamchk —keys-used=O -rq /путь/к/базе_данных/имя_таблицы.
Это отключит использование всех индексов таблицы при загрузке.
4. Вставьте данные в таблицу с помощью LOAD DATA INFILE. Это не будет обнов-
лять индексы, поэтому выполнится очень быстро.
5. Если предполагается, что в будущем таблица будет служить только для чте-
ния, с помощью myisampack уменьшите ее размер (см. раздел 8.1.3.3).
6. Пересоздайте индексы с помощью команды myisamchk -r -q /путь/к/базе_дан-
ных/имя_таблицы. Это создаст дерево индекса в памяти, прежде чем записать
его на диск, что гораздо быстрее, так как позволяет избежать множества опе-
раций доступа к диску. Результирующее дерево индекса к тому же лучше сба-
лансировано.
7. Выполните оператор FLUSH TABLES или команду mysqladmin flush-tables.
Имейте в виду, что LOAD DATA INFILE также выполняет предварительную оптими-
зацию, если вставка выполняется в пустую таблицу My ISAM. Главное отличие со-
стоит в том, что вы можете позволить myisamchk выделить гораздо больше вре-
426 Глава 6. Оптимизация MySQL

менной памяти для создания индексов, чем это делает сервер при пересоздании
индексов, когда он выполняет LOAD DATA INFILE.
Начиная с MySQL 4.0, можно использовать также ALTER TABLE имя_таблицы
DISABLE KEYS вместо myisamchk --keys-used=O -rq /путь/к/базе_данных/
имя_таблицы и ALTER TABLE имя_таблицы ENABLE KEYS вместо myisamchk -r -q
/путь/к/базе_данных/имя_таблицы. При этом шаг FLUSH TABLES можно пропустить.
• Вы можете увеличить скорость операции вставки, которая выполняется несколь-
кими операторами, если заблокируете таблицы:
LOCK TABLES a WRITE;
INSERT INTO a VALUES (1,23), (2,34), (4,33);
INSERT INTO a VALUES (8, 26), (6,29) ;
UNLOCK TABLES;
Выигрыш в производительности появляется за счет того, что индексный буфер
сбрасывается на диск только один раз, после того, как завершатся все операторы
INSERT. Явные операторы блокировки не требуются, если вы можете вставить все
строки одним оператором.
Для транзакционных таблиц, чтобы поднять скорость, нужно использовать блоки
BEGIN/COMMIT в м е с т о LOCK TABLES.
Блокировка также снижает общее время выполнения тестов со многими соедине-
ниями, несмотря на то что максимальное время ожидания индивидуальных со-
единений может возрасти, поскольку они ожидают снятия блокировок. Например:
Connection I does 1000 inserts
Connections 2, 3, and 4 do 1 insert
Connection 5 does 1000 inserts
Если вы не применяете блокировки, соединения 2, 3 и 4 завершатся перед соеди-
нениями 1 и 5. Если же они используются, возможно, что соединения 2, 3 и 4 не
завершатся перед соединениями 1 и 5, однако общая скорость будет на 40% выше.
Операции INSERT, UPDATE и DELETE в MySQL выполняются очень быстро, но вы по-
лучите лучшую общую производительность, добавив блокировки вокруг всего, что
делает больше, чем 5 вставок или обновлений строк. Если вы делаете очень много
вставок, то можете выполнять LOCK TABLE с последующим UNLOCK TABLE периоди-
чески (с интервалом в 1000 строк), чтобы позволить другим пользователям иметь
доступ к таблице. Это также даст хороший выигрыш в производительности.
INSERT все еще работает значительно медленнее при загрузке данных, чем LOAD
DATA INFILE, даже если используются описанные выше стратегии.
• Чтобы получить еще некоторое приращение скорости для таблиц My ISAM как при
использовании INSERT, так и при LOAD DATA INFILE, можно увеличить значение
системной переменной key_buffer_size. См. раздел 6.5.2.

6.2.13. Скорость выполнения запросов UPDATE


Запросы на обновление оптимизируются как запрос SELECT с дополнительной на-
грузкой в виде записи. Скорость записи зависит от объема данных, которые нужно об-
новить, и количества обновляемых индексов. Индексы, которые не изменяются, обнов-
ляться не будут.
6.2. Оптимизация операторов SELECT и других запросов 427

Другой способ получить быстрые обновления - это отложить их и позже сделать


множество обновлений сразу. Выполнение групповых обновлений происходит значи-
тельно быстрее, чем по одному, если заблокировать таблицу.
Следует отметить, что для таблиц My ISAM, которые используют динамический формат
записей, обновление записи с увеличением ее общей длины может разделить запись.
Если вы делаете это часто, очень важно периодически выполнять OPTIMIZE TABLE.

6.2.14. Скорость выполнения запросов DELETE


Время на удаление отдельных записей прямо пропорционально количеству индексов.
Чтобы удалять записи быстрее, можно увеличить размер кэша ключей. См. раздел 6.5.2.
Если вы хотите удалить все строки в таблице, лучше применяйте TRUNCATE TABLE
имя_таблицы, чем DELETE FROM имя__таблицы.

6.2.15. Другие советы по оптимизации


В этом разделе представлены разнообразные советы по увеличению скорости выпол-
нения запросов:
• Используйте постоянные соединения, чтобы исключить затраты на подключения.
Если вы не можете применять постоянные соединения и инициируете множество
подключений к базе данных, можно изменить переменную thread_cache_size
(см. раздел 6.5.2).
• Всегда проверяйте все выдаваемые запросы - действительно ли они используют
созданные вами индексы таблиц. В MySQL это можно сделать с помощью опера-
тора EXPLAIN (см. раздел 6.2.1).
• Старайтесь не применять сложных запросов SELECT к таблицам My ISAM, которые
часто обновляются, чтобы избежать проблем с блокировками, обусловленными
конкуренцией между чтением и записью.
• В таблицы My ISAM, в которых нет удаленных строк, можно выполнять вставку но-
вых строк в конец таблицы одновременно с выполнением запросов на чтение. Ес-
ли для вас это важно, вам стоит рассмотреть возможность такого применения этих
таблиц, которое исключает удаление строк. Другая возможность - это запускать
OPTIMIZE TABLE после удаления большого количества строк.
• Используйте ALTER TABLE... ORDER BY выражение lf выражение 2, . .., если вы в
основном извлекаете строки в порядке выражение 1, выражение2, . . . Применяя это
средство после проведения интенсивных изменений в таблице, вы можете полу-
чить более высокую производительность.
• В некоторых случаях имеет смысл представить столбец, как "хешируемый" на ос-
нове информации из других столбцов. Если столбец короткий и в достаточной
степени уникальный, это может работать значительно быстрее, чем большой со-
ставной индекс по многим столбцам. В MySQL очень просто использовать такой
добавочный столбец:
SELECT * FROM имя_таблицы
WHERE хешируеьшй_столбеигШЬ (CONCAT {столбец!, столбец2))
AND coll='константа* AND co!2='константа';
428 Глава 6. Оптимизация MySQL

• В интенсивно изменяемых таблицах My ISAM нужно стараться избегать применения


столбцов переменной длины (VARCHAR, BLOB и TEXT). Даже если таблица включает
в себя всего один такой столбец, она будет использовать динамический формат
записей. См. главу 8.
• Обычно не стоит разделять одну таблицу на две или несколько только из-за того,
что строки стали "большими". При обращении к строке, прежде всего на произво-
дительность влияет время доступа к диску - время поиска первого байта строки.
После того, как первый байт найден, большинство современных дисков могут
прочесть всю строку достаточно быстро для большинства приложений. Единст-
венный случай, когда действительно имеет смысл разбить таблицу - это если речь
идет о таблице My ISAM с динамическим форматом записи (см. выше), которую вы
можете привести к формату фиксированного размера строки, или же вам очень
часто нужно выполнять ее полное сканирование, при этом не нуждаясь в боль-
шинстве столбцов. См. главу 8.
• Если часто требуется вычислять результаты, подобные счетчику итоговых значе-
ний, на основании множества строк, возможно, будет гораздо лучше ввести но-
вую таблицу и обновлять счетчик в реальном времени. Обновление следующего
типа работает очень быстро:
UPDATE имя таблицы SET столбец_счетчика~столбец счетчика+1
WHERE ключевой_столбец=константа ;
Это действительно важно, когда вы применяете механизмы хранения MySQL, та-
кие как My ISAM и ISAM, у которых есть только блокировка уровня таблицы (множе-
ство чтений/одна запись). Но это также повысит производительность и в боль-
шинстве других баз данных, поскольку диспетчеру блокировок строк в этом слу-
чае придется выполнять меньше работы.
• Если вам нужно собирать статистику из больших таблиц протоколов, применяйте
итоговые таблицы вместо регулярного сканирования этих больших таблиц. Под-
держка таблиц итогов значительно проще, чем вычисление итогов "вживую". Го-
раздо быстрее регенерировать новые итоговые таблицы, когда что-то изменяется
в зависимости от бизнес-решений, чем вносить эти изменения в работающие при-
ложения.
• Если возможно, вы должны разделить отчеты на "живые" и "статистические", при
этом данные, необходимые для статистических отчетов, выбираются только из
итоговых таблиц, которые генерируются периодически из живых данных.
• Воспользуйтесь преимуществом того факта, что столбцы имеют значения по
умолчанию. Вносите явно только те данные, что отличаются от значений по
умолчанию. Это сократит затраты времени MySQL на разбор SQL-операторов и
повысит скорость вставки.
• В некоторых случаях удобно упаковывать данные и сохранять их в столбцы типа
BLOB. Конечно, при этом придется добавлять дополнительный код в приложения,
чтобы упаковывать и распаковывать информацию из значений BLOB, но на опре-
деленном этапе это может помочь сэкономить на чтении. Это достаточно прак-
тично, когда характер данных не приспособлен к хранению в табличной структу-
ре типа "строка-столбец".
6.2. Оптимизация операторов SELECT и других запросов 429

• Обычно вы должны стараться избегать избыточности данных (что в теории реля-


ционных баз данных называется "третьей нормальной формой"). Однако не бой-
тесь дублировать информацию или создавать итоговые таблицы, если необходимо
добиться более высокой скорости.
• Хранимые процедуры и функции, определяемые пользователем (User-Defined
Functions - UDF) могут оказаться хорошим способом повышения производитель-
ности для некоторых задач. Однако если вы работаете с базой данных, которая не
поддерживает этих средств, у вас должен быть другой способ выполнения тех же
задач, даже если этот другой способ медленнее.
• Вы всегда можете выиграть что-то, кэшируя запросы или ответы на уровне ваших
приложений с последующим выполнением всех вставок и обновлений вместе. Ес-
ли ваша база данных поддерживает блокировку таблиц (как MySQL и Oracle), это
поможет гарантировать, что кэш индекса будет сброшен только однажды, после
всех изменений.
• Используйте INSERT DELAYED, если вам не обязательно знать, когда записаны ва-
ши данные. Это повышает скорость, потому что множество строк могут быть за-
писаны на диск в один прием.
• Используйте INSERT LOW_PRIORITY, когда хотите дать операторам SELECT более
высокий приоритет, чем операторам вставки строк.
• Используйте SELECT LOWPRIORITY, когда нужно, чтобы запрос "перепрыгивал"
очередь. То есть, SELECT будет выполняться, даже если другой клиент ожидает
возможности выполнить запись.
• Используйте многострочные операторы INSERT, чтобы сохранять много строк од-
ним оператором (многие SQL-серверы поддерживают это).
• Используйте LOAD DATA INFILE для загрузки больших объемов данных. Это быст-
рее, чем применение операторов INSERT.
• Используйте столбцы AUTOINCREMENT для генерации уникальных значений.
• Используйте OPTIMIZE TABLE от случая к случаю, чтобы избежать фрагментации
таблиц MylSAM, когда применяется формат динамических таблиц. См. раздел 8.1.3.
• Когда это возможно, используйте НЕАР-таблицы, чтобы получить высокую ско-
рость. См. главу 8.
• Когда применяется нормальная настройка Web-сервера, графические изображе-
ния должны храниться в виде файлов. Поэтому храните в базе данных только
ссылки. Главная причина состоит в том, что Web-серверы гораздо лучше кэши-
руют файлы, чем содержимое баз данных, поэтому намного легче получить быст-
рую систему, применяя файлы.
• Используйте таблицы в памяти для некритичных данных, к которым обращаются
часто, таких как информация о последнем рекламном баннере, показанном поль-
зователю, который отключил cookie в своем браузере.
• Столбцы с идентичной информацией в разных таблицах должны быть объявлены
с одинаковыми типами данных. В противном случае до версии MySQL 3.23 со-
единения работали медленно.
430 Глава 6. Оптимизация MySQL

• Старайтесь использовать простые имена столбцов. Например, в таблице customer


используйте имя столбца name вместо customer_name. Чтобы сделать имена пере-
носимыми на другие SQL-серверы, их длина не должна превышать 18 символов.
• Если вам нужна действительно высокая скорость, стоит обратить внимание на
низкоуровневые интерфейсы доступа к данным, которые поддерживают различ-
ные SQL-серверы. Например, работая напрямую с механизмом хранения MySAM в
MySQL, вы можете добиться от двукратного до четырехкратного повышения ско-
рости по сравнению с SQL-интерфейсом. Чтобы иметь возможность сделать это,
данные должны находиться на том же сервере, что и приложения, и обычно они
должны быть доступны только одному процессу (поскольку внешняя блокировка
файлов действительно медленна). Это проблему можно было бы решить вводом
низкоуровневых команд на сервере MySQL (и это был бы простой путь для полу-
чения высокой производительности). При тщательной разработке конструкции
интерфейса баз данных было бы достаточно просто поддерживать такой тип оп-
тимизации.
• Если вы работаете с числовыми данными, во многих случаях быстрее иметь дос-
туп к данным в базе (при живом соединении), чем в текстовом файле. Информа-
ция в базе, скорее всего, будет храниться в более компактном формате, чем в тек-
стовом файле, поэтому обращение к ней требует меньших затрат на чтение с дис-
ка. Вы также экономите на коде приложений, так как нет необходимости
выполнять разбор текстовых файлов, чтобы найти строку и границы столбцы.
• Для некоторых операций выигрыш в производительности может обеспечить реп-
ликация. Вы можете распределять клиентские запросы по реплицируемым серве-
рам, таким образом, балансируя нагрузку. Чтобы избежать замедления работы
главного сервера во время создания резервных копий, это можно поручить подчи-
ненным серверам. См. главу 5.
• Объявление таблицы MylSAM с табличной опцией DELAY_KEY_WRITE=1 ускоряет об-
новление индексов, поскольку они не сбрасываются на диск вплоть до закрытия
таблицы. Недостаток такого подхода состоит в том, что если после открытия таб-
лиц сервер выходит из строя, обязательно потребуется выполнить проверку таб-
лиц, запустив сервер с опцией —my is am-re cove r или воспользовавшись програм-
мой myisamchk. Только после выполнения проверки можно будет нормально за-
пустить сервер. (Следует заметить, однако, что вы ничего не потеряете, используя
DELAY_KEY_WRITE, поскольку ключи всегда могут генерироваться на основе строк
данных.)

6.3. Вопросы блокировки


6.3.1. Методы блокировки
В настоящий момент MySQL поддерживает блокировку на уровне таблицы для таб-
лиц ISAM, My ISAM и MEMORY (HEAP), блокировку уровня страницы для таблиц BDB и блоки-
ровку уровня строки - для таблиц InnoDB.
Во многих случаях вы можете сделать квалифицированные предположения о том,
какой тип блокировки лучший для приложения, но, в общем, очень трудно принять ре-
шение в пользу того или иного типа блокировки. Все зависит от приложений, и разные
части одного и того же приложения могут требовать блокировок различных типов.
6.3. Вопросы блокировки 431

Чтобы решить, хотите ли вы использовать механизм хранения с блокировками уров-


ня строки, нужно посмотреть, что делает ваше приложение и в какой пропорции оно
использует запросы на выборку данных и на их обновление. Например, большинство
Web-приложений выполняют множество выборок, очень мало удалений, обновления
основаны в основном на значениях ключей, а вставки - только в некоторые специфиче-
ские таблицы. Базовый тип таблиц MySQL - MylSAM - очень хорошо подходит для такого
режима работы.
Система блокировки уровня таблиц в MySQL свободна от взаимных блокировок
(deadlock) в тех механизмах хранения, которые ее поддерживают. Избежание взаимных
блокировок осуществляется тем, что всегда запрашиваются все необходимые блокиров-
ки в начале запроса и таблицы блокируются в одном и том же порядке.
Метод блокировки таблиц при записи MySQL работает следующим образом:
• Если в данный момент на таблице нет блокировок, поставить блокировку записи.
• В противном случае поставить запрос на блокировку в очередь запросов блокиро-
вок записи.
Метод блокировки таблиц при чтении MySQL работает следующим образом:
• Если в данный момент на таблице нет блокировок записи, поставить блокировку
чтения.
• В противном случае поставить запрос на блокировку в очередь запросов блокиро-
вок чтения.
Когда блокировка снята, возможность установки следующей предоставляется пото-
кам, ожидающим в очереди блокировок записи, а затем - ожидающим в очереди блоки-
ровок чтения.
Это означает, что если в таблице проводится много обновлений, то операторы SELECT
будут ожидать, пока все они не выполнятся.
Начиная с версии MySQL 3.23.33, вы можете анализировать состояние конкурирую-
щих блокировок в системе, проверяя состояние переменных Table_locks_waited и
Table_locks_immediate:
mysql> SHOW STATUS LIKE 'Table%f;
+ + +
| Variablename | Value |

I Table_locks_immediate I 1151552 |
I Table_locks_waited | 15324 |
+ + +
Что касается MySQL 3.23.7 (3.23.5 для Windows), при работе с таблицами MylSAM вы
можете свободно смешивать параллельные операторы INSERT и SELECT без блокировок,
если только операторы INSERT не конкурируют между собой. То есть можно вставлять
строки в таблицы MylSAM, в то время как другой клиент осуществляет чтение из них. Ни-
каких конфликтов не возникает, если файл данных не содержит свободных блоков в се-
редине, так как в этом случае записи всегда вставляются в конец файла. (Пустоты могут
образоваться в результате удаления или обновления строк, находящихся в средине таб-
лицы.) Если есть пустоты, параллельные вставки будут включены автоматически, когда
они все будут заполнены новыми данными.
Если вы хотите выполнять множество операторов INSERT и SELECT на таблице в мо-
мент, когда параллельные вставки невозможны, вы можете вставлять строки во времен-
432 Глава 6. Оптимизация MySQL

ный файл и обновлять реальную таблицу записями из этого временного файла периоди-
чески. Это можно сделать с помощью следующего кода:
mysql> LOCK TABLES real_table WRITE, insert_table WRITE;
mysql> INSERT INTO real_table SELECT * FROM insert_table;
mysql> TRUNCATE TABLE insert_table;
mysql> UNLOCK TABLES;
InnoDB использует блокировки строк, a BDB - блокировки страниц. Для механизмов
хранения InnoDB и BDB взаимные блокировки возможны. Это объясняется тем, что
InnoDB автоматически вызывает блокировки строк, a BDB - блокировки страниц при вы-
полнении SQL-операторов, а не в начале транзакции.
Преимущества блокировки строк таковы:
• Меньше блокировок конфликтуют между собой, когда разные потоки работают с
разными строками.
• Меньше изменений для отката.
• Есть возможность держать блокировку отдельной строки в течение длительного
времени.
Ниже представлены недостатки блокировки строк:
• Требуется больше памяти, чем при блокировке на уровне таблиц или на уровне
страниц.
• Медленнее работает, чем блокировка уровня страниц или уровня таблиц, особен-
но когда применяется к значительной части таблицы, поскольку нужно выполнить
намного больше индивидуальных блокировок.
• Определенно гораздо хуже, чем другие типы блокировок, если вы часто выпол-
няете операции GROUP BY на значительной части данных, или если вы часто долж-
ны сканировать всю таблицу.
• При высокоуровневом блокировании гораздо проще поддерживать блокировки
других типов для настройки приложения, потому что у них нагрузка, связанная с
блокировками, меньше, чем при блокировках уровня строки.
Блокировки таблиц превосходят блокировки уровня страниц или уровня строк в сле-
дующих случаях:
• Большинство операторов, выполняемых в таблице, связано с чтением.
• Чтения и обновления по строгим ключам, когда вы модифицируете или удаляете
строку, которая может быть извлечена единственным чтением ключа:
UPDATE имя_таблицы SET столбец=значение
WHERE столбец_уникального_ключа=зна чение_ключа ;
DELETE FROM имя_таблицы WHERE столбец_уникального_ключа=значение_ключа;
• Операторы SELECT комбинируются с операторами INSERT и очень малым количе-
ством операторов UPDATE И DELETE.
• Выполняется много полных сканирований таблиц и операций GROUP BY без необ-
ходимости записи.
Ниже указаны альтернативы блокировкам строк и страниц.
Управление версиями (такое, как мы используем в MySQL для параллельных вста-
вок), когда вы можете иметь одну операцию записи одновременно со многими опера-
6.3. Вопросы блокировки 433

циями чтения. Это означает, что база/таблица поддерживают разные взгляды на данные
в зависимости от того, когда вы начинаете доступ к ним. Другие названия для этого: пе-
ремещение во времени, копирование по записи или копирование по требованию.
Копирование по требованию во многих случаях гораздо лучше, чем блокировка
уровня страницы или уровня строки. Однако в худшем случае использует больше памя-
ти, чем когда применяется нормальная блокировка.
Вместо применения блокировок уровня строки можно использовать блокировки
уровня приложения, такие как GETLOCKO и RELEASE_LOCK () в MySQL. Это экспертные
блокировки, поэтому они работают только в хорошо работающих приложениях.

6.3.2. Вопросы блокировки таблиц


Для достижения очень высокой скорости MySQL использует блокировки таблиц
(вместо блокировок страниц, строк или столбцов) во всех механизмах хранения, кроме
InnoDB и BDB.
Для InnoDB и BDB MySQL применяет блокировку таблиц, только если это сделано яв-
но с помощью вызова LOCK TABLES. Для этих типов таблиц мы вообще не рекомендуем
использовать LOCK TABLES, поскольку таблицы InnoDB используют автоматическую бло-
кировку строк, a BDB - блокировку страниц, чтобы гарантировать изоляцию транзакций.
В больших таблицах для большинства приложений блокировка уровня таблицы го-
раздо лучше, чем блокировка уровня строки, однако, существуют некоторые подводные
камни.
Блокировка таблицы позволяет многим потокам читать данные из таблицы одновре-
менно, но если поток собирается записывать в таблицу, он должен сначала получить
эксклюзивный доступ. В процессе обновления данных все остальные потоки, которым
нужен доступ к таблице, вынуждены ожидать, пока обновление не завершится.
Обновления таблиц обычно рассматриваются как более важная операция, чем извле-
чение данных, поэтому им присваивается более высокий приоритет. Это должно гаран-
тировать, что обновления таблицы не "истощатся", даже если в среде высока активность
запросов SELECT.
Блокировка таблиц вызывает проблемы в случаях, подобных тому, когда поток ожи-
дает, поскольку диск переполнен и требуется дополнительно свободное пространство,
чтобы поток продолжил работу. В этом случае все потоки, которым нужен доступ к про-
блемной таблице, также будут находиться в состоянии ожидания до тех пор, пока не
будет выделено это свободное пространство.
Табличная блокировка также невыгодна при следующем сценарии событий:
• Клиент выдает оператор SELECT, который долго выполняется.
• Другой клиент следом запускает оператор UPDATE для той же таблицы. Этому кли-
енту придется ждать, пока не завершится первый SELECT.
• Другой клиент выдает другой оператор SELECT для той же таблицы. Поскольку
UPDATE имеет более высокий приоритет, чем SELECT, последнему SELECT придется
ждать, пока не завершится UPDATE. Он также будет ждать завершения первого
SELECT!
В следующем списке представлены некоторые способы минимизации противоречий,
связанных с блокировкой таблиц.
• Постарайтесь добиться, чтобы SELECT выполнялся быстрее. Чтобы это сделать,
можно создать итоговые таблицы.
434 Глава 6. Оптимизация MySQL

• Запустите mysqld с опцией —low-priority-updates. Это назначит всем операто-


рам, модифицирующим данные, более низкий приоритет, чем операторам SELECT.
В этом случае следующий оператор SELECT из предыдущего сценария будет вы-
полнен перед оператором UPDATE и ему не придется ожидать завершения первого
SELECT.

• Можно указать, что все обновления, исходящие из определенного клиентского


соединения, должны выполняться с пониженным приоритетом, дав команду SET
LOW_PRIORITY_UPDATES=1.
• Можно назначить конкретному оператору INSERT, UPDATE или DELETE пониженный
приоритет с помощью атрибута LOW_PRIORITY.
• Можно назначить конкретному оператору SELECT повышенный приоритет, при-
менив атрибут HIGH_PRIORITY.
• Начиная с MySQL 3.23.7, можно запускать mysqld с низким значением системной
переменной max_write_lock_count, чтобы заставить MySQL временно повышать
приоритет всех операторов SELECT, которые находятся в состоянии ожидания, по-
сле того, как произойдет заданное количество операций вставки. Это позволяет
установить блокировку READ после некоторого количества блокировок WRITE.
• Если у вас возникают проблемы с INSERT в комбинации с SELECT, переключитесь
на использование таблиц My ISAM, которые поддерживают параллельную работу
SELECT И INSERT.
• Если вы смешиваете вставки и удаления в одной и той же таблице, очень поможет
INSERT DELAYED.

• Если у вас возникают проблемы с SELECT в комбинации с DELETE, может помочь


опция LIMIT для оператора DELETE.
• Применение SQL_BUFFER_RESULTS с операторами SELECT может уменьшить про-
должительность времени блокировки таблицы.
• Можно внести изменение в программный код блокировки в mysys/thr_lock. с для
использования единственной очереди. В этом случае блокировки записи и блоки-
ровки чтения будут иметь одинаковые приоритеты, что может помочь в некото-
рых приложениях.
Вот некоторые советы по использовании блокировок таблиц в MySQL:
• Конкуренция пользователей не является проблемой, если вы не смешиваете об-
новления с выборками, которые имеют дело с большим количеством строк.
• Для ускорения вы можете использовать LOCK TABLES (много обновлений внутри
одной блокировки работают гораздо быстрее, чем обновления без явных блокиро-
вок). Разнесение содержимого одной таблицы по нескольким таблицам также мо-
жет помочь.
• Если вы столкнулись с проблемой скорости при блокировке таблиц MySQL, вы
можете повысить производительность, преобразовав некоторые из таблиц в фор-
мат innoDB или BDB. См. главу 9 и раздел 8.4.
6.4. Оптимизация структуры базы данных 435

6.4. Оптимизация структуры базы данных


6.4.1. Конструкторские решения
MySQL содержит данные строк и данные индексов в отдельных файлах. Многие
(почти все) другие базы данных смешивают информацию строк и индексную информа-
цию в одной таблице. Мы верим, что вариант, реализованный в MySQL, лучше для
очень широкого диапазона современных систем.
Другой способ предусматривает хранение информации каждого столбца в отдельной
области (примерами могут служить SDBM и Focus). Это наносит ущерб производитель-
ности при каждом запросе, который обращается более чем одному столбцу. Поскольку
это происходит очень часто, мы уверены, что такая модель не особенно хороша для баз
данных общего назначения.
Более общий случай - это когда данные и индексы хранятся вместе (как у Oracle,
Sybase и других). В этом случае информация строк таблицы находится на конечных
страницах (листьях) индексов (верно лишь отчасти, если речь идет о кластерных индек-
сах Sybase -прим. перев.). Преимущество такого варианта заключается в том, что если
индекс хорошо кэширован, экономятся обращения к диску. Недостатки же следующие:
• Сканирование таблиц значительно медленнее, поскольку нужно читать индексы
для того, чтобы получить данные (это не совсем верно, по крайней мере, в Oracle
не требуется читать индекс, если оптимизатор решает его не использовать - прим.
перев.).
• Невозможно использовать только индексные таблицы, чтобы извлечь данные для
запроса (это не совсем верно, так как и в Oracle, и в Sybase при извлечении
столбцов, участвующих в ключе индекса, используется только индекс, а доступ к
самой таблице не требуется - прим. перев.).
• Вы теряете большой объем пространства, поскольку вынуждены дублировать ин-
дексы из узлов (поскольку не в состоянии хранить строки в узлах (это не касается
кластерных индексов Sybase - прим. перев.)).
• Удаления приводят к деградации таблиц со временем, поскольку индексы в узлах
обычно не обновляются при удалении (опять неверно! По крайней мере, принцип
разделения табличного пространства на сегменты и экстенты в Oracle с возмож-
ностью указания предельных процентных значений их наполнения снимает эту
проблему - прим. перев.)).
• Труднее кэшировать только индексные данные.

6.4.2. Делайте объем данных как можно меньше


Один из основных принципов оптимизации заключается в том, что нужно проекти-
ровать таблицы так, чтобы они занимали как можно меньше места на диске. Это может
дать огромный выигрыш производительности, поскольку чтения диска выполняются
быстрее и маленькие таблицы обычно требуют меньше основной памяти, в то время как
ее содержимое интенсивнее используется при выполнении запросов. Индексация также
в меньшей степени обременяет систему, если выполняется на маленьких столбцах.
MySQL поддерживает множество разных типов таблиц и форматов строк. Для каж-
дой таблицы вы можете принимать решения, какие методы хранения/индексации приме-
нять. Выбор правильного формата таблиц для вашего приложения может дать большой
выигрыш производительности. См. главу 8.
436 Глава 6. Оптимизация MySQL

Вы можете добиться лучшей производительности и минимизировать место, необхо-


димое для хранения данных, используя описанные ниже приемы.
• Применяйте самые эффективные (компактные) из возможных типы данных.
MySQL поддерживает много специализированных типов, которые экономят дис-
ковое пространство и память.
• Применяйте более компактные целочисленные типы, чтобы сделать таблицы
меньше. Например, MEDIUMINT обычно лучше, чем INT.
• Если возможно, объявляйте столбцы как NOT NULL. Это делает все быстрее и эко-
номит один бит на столбец. Если вам действительно требуется NULL в ваших при-
ложениях, вы, конечно, можете его применять. Просто избегайте того, чтобы это
было свойством всех столбцов по умолчанию.
• Для таблиц MylSAM, если в них нет столбцов переменной длины (VARCHAR, TEXT или
BLOB), применяется формат записей с постоянной длиной. Это работает быстрее,
но, к сожалению, приводит к расходу дискового пространства. См. раздел 8.1.3.
• Первичный индекс таблицы должен быть коротким, насколько возможно. Это
обеспечивает простую и эффективную идентификацию каждой строки.
• Создавайте только те индексы, в которых действительно нуждаетесь. Индексы
хороши для извлечения данных, но плохи, если вы хотите, чтобы сохранение дан-
ных было быстрым. Если вы в основном осуществляете доступ к таблице поиском
по комбинации столбцов, создайте индекс по ним. Первой частью ключа индекса
должна быть наиболее используемая столбец. Если вы всегда используете много
столбцов, то должны использовать столбец с большим количеством дубликатов
первым, чтобы получить лучшее сжатие индекса.
• Весьма вероятно, что столбец имеет уникальный префикс в первых нескольких
символах, тогда имеет смысл создать индекс по этому префиксу. MySQL поддер-
живает индексы по левой части символьных столбцов. Более короткие индексы
быстрее не только потому, что занимают меньше места на диске, но и потому, что
дают больше попаданий при обращении к индексному кэшу, а потому требуют
меньше обращений к диску. См. раздел 6.5.2.
• В некоторых обстоятельствах может оказаться выгодным разделение таблицы,
которая сканируется наиболее часто, на две.

6.4.3. Индексы столбцов


Все типы столбцов в MySQL могут быть индексированы. Применение индексов на
соответствующих столбцах - лучший способ повысить производительность операций
SELECT.
Максимальное количество индексов на таблицу и максимальная длина ключа индек-
са для каждого механизма хранения имеет свои значения (см. главу 8). Все механизмы
хранения поддерживают, как минимум, 16 индексов на таблицу и общую длину ключа
индекса, как минимум, в 256 байт. У большинства механизмов хранения значения этих
ограничений выше.
Используя синтаксис имя_столбца {длина) в спецификации индекса, можно создать
индекс, ключом которого служат только первые длина символов столбца типа CHAR или
VARCHAR. Индексируя подобным образом только префикс значений столбца, можно соз-
дать гораздо меньший по размеру индексный файл.
6.4. Оптимизация структуры базы данных 437

Механизмы хранения MylSAM и (начиная с MySQL 4.0.14) innoDB, также поддержива-


ют индексацию столбцов типа TEXT и BLOB. При индексации этих столбцов вы должны
указать длину префикса, используемую в ключе индекса, например:
CREATE TABLE t e s t (blob_col BLOB, INDEX(blob_col(10)));
Длина префикса может быть до 255 байтов (или 1000 байтов для таблиц MylSAM и
InnoDB, как в версии MySQL 4.1.2). Обратите внимание, что ограничение длины префик-
са измеряется в байтах, в то время как длина префикса в операторе CREATE TABLE интер-
претируется как количество символов. Имейте это в виду, когда указываете длину пре-
фикса для столбца, использующего многобайтный набор символов.
Начиная с MySQL 3.23.23, вы можете также создавать индексы FULLTEXT. Они ис-
пользуются для полнотекстового поиска. Индексы FULLTEXT поддерживаются только
таблицами типа MylSAM, и только для столбцов типа CHAR, VARCHAR и TEXT. Индексация в
них всегда выполняется по всей столбце, а индексы, основанные на части столбцы (пре-
фиксные) не поддерживаются
Начиная с MySQL 4.1.0, можно создавать индексы на пространственных (spatial) ти-
пах столбцов. В настоящее время пространственные типы поддерживаются только меха-
низмом хранения MylSAM. Пространственные индексы используют R-деревья.
Механизм хранения таблиц MEMORY (HEAP) поддерживает хеш-индексы. Начиная с
MySQL 4.1.0, этот механизм также поддерживает индексы на основе В-деревьев (бинар-
ных деревьев).

6.4.4. Составные индексы


MySQL может создавать индексы с ключом, состоящим из нескольких столбцов. Ин-
декс может состоять максимум из 15 столбцов. Для некоторых типов столбцов можно
индексировать префиксы значений столбцов (см. раздел 6.4.3).
Составные индексы можно рассматривать как отсортированные массивы, которые
содержат значения, составленные из нескольких индексированных столбцов.
MySQL использует составные индексы таким образом, что выполнение запросов ус-
коряется, когда вы указываете известное количество первых столбцов ключа индекса в
конструкции WHERE, даже если не указываете значений других столбцов.
Предположим, что таблица имеет следующее определение:
CREATE TABLE t e s t (
i d INT NOT NULL,
l a s t _ n a m e CHAR(30) NOT NULL,
f i r s t _ n a m e CHAR(30) NOT NULL,
PRIMARY KEY ( i d ) ,
INDEX name ( l a s t _ n a m e , f i r s t _ n a m e ) ) ;

Индекс name построен на основе значений столбцов last_name и first_name. Этот


индекс может быть использован при выполнении запросов, для которых указаны значе-
ния lastname в заданном диапазоне, или значения обеих столбцов - и first_name, и
last name. Таким образом, индекс name будет задействован при выполнении следующих
запросов:
SELECT * FROM t e s t WHERE last_name='Widenius';
SELECT * FROM t e s t
WHERE l a s t name='Widenius' AND f i r s t name='Michael';
438 Глава 6. Оптимизация MySQL

SELECT * FROM test


WHERE last_name='Widenius'
AND (first_name='Michael' OR first_name='Monty1);
SELECT * FROM test
WHERE last_name='Widenius'
AND first_name >='M' AND first_name < 'N f ;
Однако индекс name не будет использован при выполнении таких запросов:
SELECT * FROM test WHERE first_name='Michael•;
SELECT * FROM test
WHERE last_name='Widenius' OR first_name='Michael';
Манера, в которой MySQL использует индексы для повышения производительности
запросов, обсуждается в следующем разделе.

6.4.5. Как MySQL использует индексы


Индексы предназначены для быстрого поиска строк с определенным значением
столбцов. Без индексов при поиске MySQL должен начать с первой записи и затем чи-
тать полностью всю таблицу, чтобы найти записи, удовлетворяющие запросу. Чем
больше таблица, тем дороже это обходится. Если у таблицы есть индекс для столбца,
указанного в запросе, MySQL может быстро определить позицию местонахождения
нужной записи в середине файла данных, без необходимости просматривать все данные
подряд. Если таблица содержит 1000 записей, то поиск по индексу будет, по крайней
мере, в 100 раз быстрее, чем последовательное чтение. Имейте в виду, что если вам
нужно просмотреть почти все 1000 строк, то лучше читать их последовательно, потому
что это минимизирует количество обращений к диску.
Большинство индексов MySQL (PRIMARY KEY, UNIQUE, INDEX и FULLTEXT) хранятся в
В-деревьях. Исключение составляют индексы на столбцах пространственных типов, ис-
пользующие R-деревья, и хеш-индексы таблиц типа MEMORY (HEAP).
Строки автоматически сжимаются удалением ведущих и завершающих пробелов.
Обычно индексы используются так, как описано выше. Специфичные для хеш-
индексов характеристики описаны в конце настоящего раздела.
Итак, индексы используются для того, чтобы:
• Быстро находить строки, удовлетворяющие условию WHERE.
• Исключать из рассмотрения лишние строки. Если существует выбор между не-
сколькими индексами, MySQL использует тот, что находит минимальное количе-
ство строк.
• Извлекать строки из других таблиц при выполнении соединений.
• Находить значения MIN () и МАХ () для специфичного проиндексированного столб-
ца ключевой_столбец. Это оптимизируется препроцессором, проверяющим, ис-
пользуется ли в конструкции WHERE выражение часть_ключа#=константа по всем
частям индекса, предшествующим ключевой_столбец в индексе. В этом случае
MySQL выполняет один поиск ключа для каждого выражения MIN () и МАХ () и за-
меняет их константами. Если все выражения заменены константами, запрос воз-
вратит управление сразу, например:
SELECT MIN (часть_ключа2), МАХ (часть_ключа2)
FROM имя таблицы WHERE часть ключа 1-10;
6.4. Оптимизация структуры базы данных 439

• Сортировать группу в таблице, если сортировка или группировка выполняется по


левому префиксу используемого ключа (например, ORDER BY часть ключа 1,
часть_ключа2). Если все части ключа имеют следующее за ними слово DESC, ключ
читается в обратном порядке. См. раздел 6.2.9.
• В некоторых случаях запрос может быть оптимизирован так, чтобы извлекать
значения, не обращаясь к строкам данных. Если запрос использует только число-
вые столбцы, которые формируют левый префикс некоторого ключа, извлекаемые
значения могут быть получены для повышения скорости только из дерева индекса:
SELECT часть_ключаЗ FROM имя_таблицы WHERE часть_ключа!=1
Предположим, что вводится следующий оператор SELECT:
mysql> SELECT * FROM имя_таблицы WHERE столбец1=значение1 AND столбец2=значение2;

Если существует составной индекс по столбец! и столбец2, соответствующие строки


могут быть извлечены непосредственно. Если существуют отдельные индексы по столб-
цам столбец1 и столбец2, оптимизатор пытается найти самый узко ограничивающий
индекс, принимая решение на основании того, какой из них возвратит меньше строк, и
использует его.
Если таблица имеет составной индекс, любой левосторонний префикс ключа может
быть использован оптимизатором для поиска строк. Например, если существует индекс
с ключом, составленным из трех столбцов (столбец!, столбец2, столбецЗ), то индексный
поиск может выполняться по (столбец!), (столбец!, столбец2) или же по (столбец!,
столбец2, столбецЗ).
MySQL не может использовать индекс, если поисковые столбцы не составляют ле-
вую часть списка столбцов составного индекса. Предположим, у вас есть следующие
операторы SELECT:
SELECT * FROM имя_таблицы WHERE столбец!^значение!;
SELECT * FROM имя_таблицы WHERE столбец2=значение2;
SELECT * FROM имя_таблицы WHERE столбец2=значение2 AND столбецЗ=значениеЗ;
Если существует индекс на (столбец!, столбец2, столбецЗ), только первый из приве-
денных запросов сможет его использовать для поиска. Второй и третий запросы в конст-
рукции WHERE содержат входящие в индекс столбцы, но они не являются левосторонним
префиксом списка столбцов, образующих этот ключ.
Индекс используется для столбцов, которые сравниваются с помощью операций =, >,
>=, <, <= и BETWEEN.
MySQL также может использовать индексы для сравнения строки по LIKE, если толь-
ко аргумент LIKE - константная строка, которая не начинается с символа шаблона. На-
пример, следующие операторы SELECT используют индексы:
SELECT * FROM имя_таблицы WHERE ключевой_столбец LIKE ' P a t r i c k ! 1 ;
SELECT * FROM имя_таблицы WHERE ключевой_столбец LIKE 'Pat%_ck!';
В первом операторе рассматриваются только строки с ' P a t r i c k ' <= ключевой_стол-
бец < ' P a t r i c l ' . Во втором операторе рассматриваются только строки с ' Pat' <= клю-
чевой_столбец < 'Раи'.
Следующие операторы SELECT индексов не используют:
SELECT * FROM имя_таблицы WHERE ключевой_столбец LIKE '%Patrick%';
SELECT * FROM имя таблицы WHERE ключевой столбец LIKE другой_столбец;
440 Глава 6. Оптимизация MySQL

В первом операторе значение LIKE начинается с шаблонного символа. Во втором


операторе значение LIKE не является константой.
Версия MySQL 4.0 и выше выполняет дополнительную оптимизацию LIKE. Если вы
применяете . . . LIKE '%строка%!, и строка не длиннее трех символов, MySQL ис-
польхует алгоритм Turbo Boyer-Moor для инициализации шаблона строки и затем при-
меняет его для более быстрого поиска.
Поиск по выражению типа имя_столбца IS NULL использует индекс, если столбец
имя_столбца проиндексирован. Любой индекс, который не перекрывает все уровни AND в
конструкции WHERE, не используется во время оптимизации запроса. Другими словами,
чтобы иметь возможность использовать индекс, его префикс должен использоваться во
всех группах условий, связанных через AND.
Следующие конструкции WHERE индекс используют:
. . . WHERE часть_индекса1=1 AND часть_индекса2=2 AND другой_столбец=3
/* индекс = 1 OR индекс = 2 */
. . . WHERE индекс=1 OR A=10 AND индекс=2
/* оптимизировано как "часть_индекса2='hello'" */
. . . WHERE часть_индекса1='hello' AND часть_индексаЗ=Ь
/* Может использовать индекс на индекс1, но не на индекс2 или индексЗ */
. . . WHERE индекс1=1 AND индекс2=2 OR индекс1=3 AND индексЗ=3;
Следующие конструкции WHERE индекс не используют:
/* часть_индекса1 не используется */
. . . WHERE часть_индекса2=1 AND часть_индексаЗ=2
/* Индекс не используется в обеих частях операции AND */
. . . WHERE индекс=\ OR A=10
/* Нет индекса, охватывающего все строки */
. . . WHERE часть_индекса1=1 OR часть_индекса2-10
Иногда MySQL не использует индекс, даже если он доступен. Это случается, когда
оптимизатор оценивает, что использование индекса потребует просмотра значительного
процента строк таблицы. (В этом случае может оказаться, что полное сканирование таб-
лицы выполнится быстрее, поскольку потребует намного меньше операций доступа к
диску.) Однако если в таком запросе указано LIMIT для извлечения лишь части строк,
MySQL все равно будет использовать индекс, так как намного быстрее сможет найти
несколько строк, чтобы вернуть результат.
Хеш-индексы обладают несколько другими характеристиками, чем те, о которых го-
ворилось до сих пор:
• Они используются только для сравнений на равенство и неравенство (= и о ) , но
работают очень быстро.
• Оптимизатор не может использовать хеш-индексы для повышения скорости опе-
раций ORDER BY. (Этот тип и индекса не может быть применен для поиска сле-
дующей позиции по порядку.)
• MySQL не может определить, даже приближенно, сколько строк находится между
двумя значениями (это нужно оптимизатору диапазонов, чтобы выбрать индекс
для использования). Это может затронуть некоторые запросы, если изменить таб-
лицу My ISAM на таблицу MEMORY с хеш-индексом.
• Для поиска строки может использоваться только полный ключ. (С индексами типа
В-деревьев любой префикс ключа может быть применен для поиска строк.)
6.4. Оптимизация структуры базы данных 441

6.4.6. Кэш ключей MylSAM


Чтобы минимизировать дисковый ввод-вывод, механизм хранения My ISAM применяет
стратегию, которая используется во многих системах управления базами данных, а
именно - механизм кэширования для сохранения в памяти наиболее часто используемых
блоков таблиц:
• Для блоков индекса создается специальная структура, называемая кэшем ключей
(буфером ключей). Эта структура содержит набор буферов, куда помещаются
наиболее часто используемые индексные блоки.
• Для блоков данных MySQL не использует специальных кэшей. Вместо этого он
полагается на файловые кэши операционной системы.
В этом разделе вначале описываются базовые операции кэша ключей My ISAM. Затем
обсуждаются усовершенствования, внесенные в MySQL 4.1, которые повышают произ-
водительность кэша ключей и позволяют лучше управлять им:
• Доступ к кэшу ключей более не сериализуется для потоков. Множество потоков
теперь могут работать с ним совместно.
• Можно настроить множество ключевых кэшей и назначить их индексам таблиц.
Механизм кэша ключей также применяется в таблицах ISAM. Однако значимость это-
го факта убывает. Таблицы ISAM используются все реже с тех пор, как в MySQL 3.23
были введены таблицы My ISAM. MySQL 4.1 продолжает развивать эту тенденцию. Меха-
низм хранения ISAM в этой версии по умолчанию отключен.
Вы можете управлять размером кэша ключей с помощью системной переменной
keybuf fer_size. Если ей присвоить значение 0, кэш ключей не применяется. Также он
не используется в случае, если значение key_buffer_size настолько мало, что невоз-
можно разместить в памяти минимальное количество блоков буферов (8).
Когда кэш ключей не задействован, доступ к индексным файлам выполняется с ис-
пользованием только встроенной буферизации, представляемой операционной системой.
(Другими словами, доступ к блокам индексов таблиц организуется в соответствии с той
же стратегией, что и к блокам данных.)
Индексный блок - это узел, непосредственно занятый в доступе к индексным фай-
лам. Обычно размер индексного блока равен размеру узла индексного бинарного дерева.
(Индексы представлены на диске с использованием структуры бинарных деревьев, или
В-деревьев. Узлы в нижней части дерева являются листьями. Узлы, находящиеся выше,
листьями не являются.)
Все буферы блоков в структуре ключевого кэша имеют одинаковые размеры. Этот
размер может быть равен, большим или меньшим, чем размер индексного блока. Обыч-
но одно из этих двух значений кратно другому.
Когда данные из любого индексного блока должны быть прочитаны, сервер вначале
проверяет, не содержится ли уже этот блок в каком-нибудь буфере блоков ключевого
кэша. Если да, сервер читает данные из него, вместо того, чтобы обращаться к диску. То
есть он читает из кэша или пишет в него вместо того, чтобы читать или писать на диск.
В противном случае сервер выбирает буфер, содержащий другой индексный блок
(или блоки), и заменяет данные в нем, копируя требуемый индексный блок таблицы. Как
только новый индексный блок попадает в кэш, данные индекса становятся доступными.
Если случается так, что выбранный для замены блок был модифицирован, этот блок
рассматривается, как "измененный" ("dirty"). При этом перед заменой его старое содер-
жимое сбрасывается в индексный файл, откуда он был прочитан.
442 Глава 6. Оптимизация MySQL

Обычно сервер следует стратегии LRU (Least Recently Used - наиболее давний ис-
пользованный). То есть для замены выбирается блок, который последний раз использо-
вался наиболее давно. Чтобы иметь возможность легко осуществлять этот выбор, мо-
дуль ключевого кэша поддерживает специальную очередь (цепочку LRU) всех исполь-
зуемых блоков, и каждый раз берет оттуда для удаления первый элемент.

6.4.6.1. Совместный доступ к кэшу ключей


До MySQL 4.1 доступ к кэшу ключей сериализовался, то есть никакие два потока не
могли иметь к нему доступ одновременно. Сервер обрабатывал очередной запрос к ин-
дексному блоку только тогда, когда заканчивал обрабатывать предыдущий. В результате
запрос на индексный блок, не содержащийся ни в одном буфере, блокировал другие по-
токи до тех пор, пока этот буфер не обновлялся, загружая требуемый блок.
Начиная с версии MySQL 4.1, сервер поддерживает совместный доступ к ключевому
кэшу:
• Буфер, который не был изменен, может быть доступен множеству потоков.
• Буфер, который был изменен, приостанавливает обращающиеся к нему потоки до
тех пор, пока не закончится обновление.
• Множество потоков могут инициировать запросы на замену блоков в кэше до тех
пор, пока они не накладываются друг на друга (то есть до тех пор, пока им нужны
разные индексные блоки и потому разные блоки в кэше, которые должны быть
заменены).
Совместный доступ к кэшу ключей позволил серверу ощутимо повысить производи-
тельность.

6.4.6.2. Множественные кэши ключей


Разделенный доступ к кэшу ключей повышает производительность, но не устраняет
полностью конкуренцию между потоками. Она все еще присутствует в работе с управ-
ляющими структурами, которые обеспечивают доступ к кэшу. Чтобы еще больше сни-
зить конкуренцию при работе с кэшем, MySQL 4.1.1 предлагает возможность использо-
вать множество кэшей ключей. Это позволяет назначать индексам таблиц разные кэши
ключей с помощью оператора CACHE INDEX.
Например, следующий оператор назначает индексам таблиц t l , t2 и t3 кэш с именем
hot_cache:
mysql> CACHE INDEX t l , t 2 , t3 IN hot_cache;

I Table | Op I Msg_type | Msg_text |


+
+ + + +
I test.tl | assign_to_keycache | status | OK |
I test.t2 | assign_to_keycache | status | OK |
I test.t3 | assign_to_keycache | status | OK |
+ + + + +
На заметку!
Если сборка сервера выполнялась с включенным механизмом хранения ISAM, то таблицы ISAM
используют механизм кэша ключей. Однако индексы ISAM используют только кэш ключей по
умолчанию и не могут быть переназначены на использование другого кэша.
6.4. Оптимизация структуры базы данных 443

Кэш ключей, указываемый в операторе CACHE INDEX, может быть создан путем уста-
новки его размера в параметре SET GLOBAL или с помощью опций запуска сервера. На-
пример:
mysql> SET GLOBAL keycachel.keyjDuffer_size=128*1024;
Чтобы уничтожить кэш ключей, установите его размер в 0:
mysql> SET GLOBAL keycachel.key_buffer_size=O;
Переменные кэшей ключей - это структурные системные переменные, которые име-
ют имя и компоненты. Для keycachel.key_buffer_size, keycachel - имя переменной
кэша, a key_buf fer_size - компонент кэша.
По умолчанию индексы таблиц назначаются главному (по умолчанию) кэшу, кото-
рый создается при запуске сервера. Когда какой-то кэш ключей разрушен, все назначен-
ные ему индексы переназначаются на главный кэш.
Для нагруженного сервера мы рекомендуем стратегию с использованием трех кэшей
ключей:
• "Горячий" (hot) кэш ключей, который занимает до 20% пространства, отведенного
всем кэшам ключей. Он используется для таблиц, которые интенсивно задейст-
вуются для поиска, но редко обновляются.
• "Холодный" (cold) кэш ключей, который занимает до 20% пространства, отведен-
ного всем кэшам ключей. Используется для интенсивно обновляемых таблиц
средних размеров, таких как временные таблицы.
• "Теплый" (warm) кэш ключей, который занимает до 60% пространства, отведен-
ного всем кэшам ключей. Это кэш ключей, используемый по умолчанию всеми
остальными таблицами.
Одной из причин для применения трех кэшей ключей является выгода от того, что
обращение к одной структуре кэша не блокирует доступа к другим. Очереди, работаю-
щие с таблицами, назначенными одному кэшу ключей, не конкурируют с очередями,
работающими с таблицами, назначенными другому кэшу. Выигрыш в производительно-
сти связан и с другими причинами:
• Горячий кэш используется только для запросов чтения, поэтому его содержимое
никогда не модифицируется. Следовательно, всякий раз, когда нужно получить
индексный блок с диска, содержимое блока кэша, выбранного для замены, не
нужно сбрасывать на диск.
• Для индексов, назначенных этому кэшу, если нет запросов, требующих сканиро-
вания индекса, существует высокая вероятность того, что индексные блоки, соот-
ветствующие промежуточным узлам индексного В-дерева, останутся в кэше.
• Операции обновления, в основном проводимые во временных таблицах, выпол-
няются гораздо быстрее, если обновляемый узел уже находится в кэше и не тре-
буется его считывать с диска. Если размер индексов временных таблиц сопоста-
вим с размером холодного кэша ключей, очень высока вероятность того, что об-
новляемый узел уже находится в кэше.

6.4.6.3. Стратегия центральной точки


По умолчанию система управления кэшами ключей MySQL 4.1 использует страте-
гию LRU для выбора блока кэша, подлежащего вытеснению, но она также поддерживает
и более изощренный метод, называемый "стратегией центральной точки".
444 Глава 6. Оптимизация MySQL

Когда используется эта стратегия, цепочка LRU делится на две части: "горячую"
подцепочку и "теплую" подцепочку. Точка раздела между ними не фиксирована, систе-
ма управления кэшем ключей заботится о том, чтобы "теплая" часть не становилась
слишком короткой, а всегда содержала как минимум key_cache_division_limit процен-
тов блоков. key_cache_division_limit - это компонент структурированной переменной
кэша ключей, поэтому его значение - это параметр, который устанавливается для каждо-
го кэша.
Когда индексный блок читается из таблицы в кэш ключей, он помещается в конец
"теплой" подцепочки. После определенного количества попаданий (доступов к блоку)
он перемещается в "горячую" подцепочку. В настоящее время количество попаданий,
необходимых для этого, одинаково для всех индексных блоков. В будущем мы сделаем
счетчик попаданий зависимым от уровня узла соответствующего блока в В-дереве ин-
декса. Для узлов, находящихся ближе к корню дерева, потребуется меньше попаданий,
чем для узлов-листьев.
Блок, выбранный для переноса в "горячую" подцепочку, помещается в ее конец. Этот
блок затем циркулирует внутри подцепочки. Если блок остается в начале подцепочки в
течение достаточно длительного времени, он вытесняется в "теплую" часть. Время, необ-
ходимое для этого, определяется компонентом key_cache_age_threshold кэша ключей.
Пороговое значение, предписывающее это, вычисляется так: для кэша ключей, со-
держащего N блоков, блок, находящийся в начале "горячей" подцепочки, к которому не
осуществлялся доступ в течение N*key_cache_age_threshold/100 попаданий, должен
быть перемещен в начало "теплой" подцепочки. Затем он становится первым кандида-
том на вытеснение, потому что блоки, подлежащие замене, всегда выбираются в начале
"теплой" подцепочки кэша.
Стратегия центральной точки помогает увеличить производительность при выполне-
нии запроса, который требует сканирования индексов и эффективно вытесняет из кэша
все индексные блоки, содержащие высокоуровневые узлы В-дерева. Чтобы избежать
этого, нужно использовать стратегию вставки центральной точки со значением
key_cache_division_limit, установленным менее 100. Полезные узлы с частыми попа-
даниями будут сохранены в "горячей" подцепочке при сканировании индексов.

6.4.6.4. Предварительная загрузка индексов


Если в кэше ключей достаточно блоков, чтобы поместить туда весь индекс целиком,
или хотя бы блоки, представляющие нелистовые узлы, имеет смысл загрузить его пред-
варительно в кэш ключей, прежде чем начать использовать. Предварительная загрузка
позволит вам поместить индексные блоки в кэш наиболее эффективным способом: по-
следовательным чтением индексных блоков.
Без предварительной загрузки блоки также будут помещаться в кэш ключей, как это
потребуется запросам. Но, несмотря на то, что блоки будут оставаться в кэше, так как
там достаточно места для них всех, все же они будут извлекаться из индекса в случай-
ном порядке, а не последовательно.
Чтобы предварительно загрузить индекс в кэш, используйте оператор LOAD INDEX
INTO CACHE. Например, следующий оператор предварительно загружает узлы (блоки)
индексов таблиц t l и t2:
mysql> LOAD INDEX INTO CACHE t l , t2 IGNORE LEAVES;

Table | Op | Msg_type | Msg text


6.4. Оптимизация структуры базы данных 445

I test.tl I preload_keys | status | OK |


I test.t2 I preload_keys | status | OK |
+ + + + +
Модификатор IGNORE LEAVES вынуждает предварительно загружать только блоки ин-
декса, не являющиеся листьями. Поэтому приведенный выше оператор загружает все
блоки индексов t l , но только нелистовые блоки t2.
Если индекс назначается кэшу ключей с помощью оператора CACHE INDEX, предвари-
тельная загрузка помещает блоки индекса в этот кэш. Иначе индекс загружается в кэш
по умолчанию.

6.4.6.5. Размер блока кэша ключей


В MySQL 4.1 введена новая переменная key_cache_block_size, своя для каждого
кэша. Она определяет размер блоков буферов кэша ключей, и предназначена для на-
стройки производительности операций ввода-вывода для индексных файлов.
Наилучшая производительность операций ввода-вывода достигается, когда размер
буферов чтения равен размеру буферов ввода-вывода операционной системы. Однако
установка размера ключевых узлов равной размеру буфера ввода-вывода не всегда га-
рантирует наилучшую производительность в итоге. При чтении больших узлов-листьев
сервер вытаскивает много ненужных данных, эффективно препятствуя чтению других
узлов.
В настоящий момент вы не можете управлять размером индексных блоков таблицы.
Этот размер устанавливается сервером при создании индексного файла .MYI, в зависи-
мости от размера ключа индекса, заданного в определении таблицы. В большинстве слу-
чаев он устанавливается равным размеру буфера ввода-вывода. В будущем это будет
изменено, и переменная key_cache_block_size будет полностью задействована.

6.4.6.6. Реструктуризация кэша ключей


Кэш ключей может быть реструктурирован в любой момент путем обновления его
параметров, например:
mysql> SET GLOBAL cold__cache.key__buffer_size=4*1024*1024;
Если присвоить новое значение компонентам кэша key_buffer_size или
key_cache_block_size, то сервер разрушит старую структуру кэша ключей и создаст
новую - на базе новых значений параметров. Если кэш содержит "измененные" блоки,
сервер сохранит их на диске прежде, чем разрушить и пересоздать кэш.
Реструктуризация не производится при изменении других параметров кэша.
При реструктуризации кэша ключей сервер первым делом сбрасывает содержимое
"измененных" блоков на диск. После этого содержимое кэша становится недоступным.
Однако при этом не блокируются запросы, которым нужны индексы, назначенные кэ-
шу. Вместо этого сервер напрямую обращается к табличным индексам, используя
только встроенное кэширование файловой системы. Кэширование файловой системы
не настолько эффективно, как кэши ключей, поэтому, хотя запросы и выполняются,
может ощущаться замедление. Как только кэш реструктурирован, он снова становится
доступным, и запросы снова используют его вместо механизма кэширования файловой
системы.
446 Глава 6. Оптимизация MySQL

6.4.7. Как MySQL подсчитывает открытые таблицы


Когда вы запускаете команду mysqladmin status, то видите нечто вроде следующего:
Uptime: 426 Running threads: 1 Questions: 11082
Reloads: 1 Open tables: 12
Значение Open tables (Отрытые таблицы), равное 12, может несколько озадачить,
если у вас всего шесть таблиц.
MySQL - система многопоточная, поэтому может оказаться, что множество клиентов
выполняют запросы к одной и той же таблице параллельно. Чтобы минимизировать про-
блемы со многими клиентскими потоками, имеющими разное состояние в одном и том
же файле, таблица открывается независимо каждым параллельным потоком. Это требует
некоторых затрат памяти, но обычно увеличивает производительность. Для таблиц
My ISAM необходим один дополнительный файловый дескриптор на файл данных для ка-
ждого клиента, который его открывает. (В отличие от этого, дескриптор индексного
файла совместно используется несколькими потоками.) Механизм хранения ISAM рабо-
тает так же.
Более подробно об этом можно прочитать в следующем разделе.

6.4.8. Как MySQL открывает и закрывает таблицы


Системные переменные table_cache, max_connections и max_tmp_tables влияют на
максимальное количество файлов, которые сервер может держать открытыми. Если вы
увеличите одно или более из этих значений, то можете столкнуться с ограничением, на-
кладываемым операционной системой на количество дескрипторов файлов, которые
может открывать один процесс. Многие операционные системы позволяют увеличивать
лимит открытых файлов, хотя способы могут варьироваться от системы к системе. Об-
ратитесь к документации по операционной системе, чтобы узнать, можно ли увеличить
этот предел, и как это сделать.
table_cache связано с max_connections. Например, при 200 активных параллельных
соединениях вам нужно иметь табличный кэш размером, по меньшей мере, 200 * А/, где
N - максимальное количество таблиц в соединении. Также нужно зарезервировать неко-
торое число файловых дескрипторов для временных таблиц и файлов.
Убедитесь, что ваша операционная система может обслуживать достаточное количе-
ство открытых файловых дескрипторов, указанное в установке table_cache. Если уста-
новлено слишком большое значение table_cache, MySQL может превысить максималь-
но возможное количество дескрипторов и отвергать соединения, отказывать в обслужи-
вании запросов и работать весьма ненадежно. Надо также принять во внимание, что
механизм хранения My ISAM нуждается в дополнительных двух дескрипторах для каждой
уникальной открытой таблицы. Вы можете увеличить количество доступных файловых
дескрипторов для MySQL, с помощью опции запуска mysqld —open-files-limit. См.
раздел А.2.17.
Кэш открытых таблиц будет сохраняться на уровне table_cache позиций. Значение
по умолчанию равно 64 и может быть изменено опцией mysqld —table_cache. Помни-
те, что MySQL может открывать даже больше таблиц для обслуживания запросов.
Неиспользуемые таблицы закрываются и удаляются из табличного кэша при сле-
дующих условиях:
6.4. Оптимизация структуры базы данных 447

• Когда кэш полон и поток пытается открыть таблицу, которая еще не содержится в
кэше.
• Когда кэш содержит больше, чем table_cache позиций, и поток больше не ис-
пользует таблицу.
• Когда выполняется операция сброса таблицы. Это происходит, если кто-то вы-
полняет оператор FLUSH TABLES либо выдает команду mysqladmin flush-tables
или mysqladmin refresh.
Когда табличный кэш наполняется, сервер использует следующую процедуру, чтобы
найти позицию в кэше для использования:
• Таблицы, которые в данный момент не используются, освобождаются в порядке
последнего обращения.
• Если требуется открыть новую таблицу, но кэш полон и никакая из таблиц не мо-
жет быть освобождена, кэш временно расширяется.
Когда кэш временно расширен, и таблица переходит в состояние неиспользуемой,
она закрывается и освобождается из кэша.
Таблица открывается для каждого параллельного доступа. Это означает, что она
должна быть открыта дважды, если потоки обращаются к одной и той же таблице, или
один поток обращается к таблице дважды в одном запросе (например, выполняя соеди-
нение таблицы с нею самой). Каждое конкурирующее открытие требует позиции в таб-
личном кэше. Первое открытие любой таблицы занимает два файловых дескриптора:
один для файла данных и один для индексного файла. Каждое дополнительное исполь-
зование таблицы требует только одного файлового дескриптора - для файла данных.
Дескриптор индексного файла используется потоками совместно.
Если вы открываете таблицу оператором HANDLER имя_таблицы OPEN, то выделенный
табличный объект распределяется для потока. Этот табличный объект не разделяется
другими потоками и не закрывается до тех пор, пока поток не выполнит оператор
HANDLER имя_таблицы CLOSE, или же его выполнение прервется. Когда это случится, таб-
лица перемещается назад в табличном кэше (если он не полон).
Вы можете определить, что ваш табличный кэш маловат, проверив переменную со-
стояния mysqld с именем Opened_tables:
mysql> SHOW STATUS LIKE 'Opened_tables';

| Variable_name | Value |
+
+ +
| Opened_tables | 2741 |
+ + +
Если значение достаточно велико, даже если вы не выполняли FLUSH TABLES, вам
стоит увеличить размер табличного кэша. См. разделы 4.2.3 и 4.2.4.

6.49. Недостатки создания множества таблиц


в одной базе данных
Если у вас много таблиц My ISAM или ISAM в каталоге базы данных, то операции созда-
ния, открытия и закрытия таблиц могут быть медленными. Если вы выполняете опера-
тор SELECT на множестве различных таблиц, будут иметь место некоторые накладные
расходы, когда табличный кэш полон, потому что для каждой таблицы, которая должна
448 Глава 6. Оптимизация MySQL

быть открыта, другая должна быть закрыта. Вы можете снизить эти накладные расходы,
увеличив размер табличного кэша.

6.5. Оптимизация сервера MySQL


6.5.1. Настройка параметров системы и запуска
Начнем с факторов уровня системы, поскольку некоторые из этих решений могут
быть приняты на ранних этапах, чтобы достичь существенного выигрыша в производи-
тельности. В других случаях беглого просмотра настоящего раздела может быть доста-
точно. Однако все же неплохо знать, что можно выиграть за счет изменений, вносимых
в настройки на этом уровне.
Выбор операционной системы, используемой по умолчанию, чрезвычайно важен!
Чтобы наилучшим образом использовать многопроцессорные машины, вы должны ис-
пользовать Solaris (потому что реализация потоков в ней работает действительно хоро-
шо) или Linux (поскольку ядро 2.2 обладает хорошей поддержкой симметричных много-
процессорных вычислений). Помните, что старые ядра Linux имели ограничение на раз-
мер файла в 2 Гбайт по умолчанию. Если у вас такое ядро и есть настоятельная
необходимость работать с файлами больше 2 Гбайт, вам следует установить исправле-
ние Large File Support (LFS) для файловой системы ext2. Другие файловые системы, та-
кие как ReiserFS или XFS, не имеют ограничений в 2 Гбайт.
Прежде чем вводить MySQL в производственную эксплуатацию, мы советуем про-
тестировать существующую платформу.
Ниже представлены другие советы.
• Если у вас достаточно оперативной памяти, можете удалить все устройства под-
качки. Некоторые операционные системы используют устройства подкачки в не-
которых контекстах, даже если оперативной памяти достаточно.
• Используйте опцию MySQL —skip-external-locking для исключения внешних
блокировок. Эта опция в MySQL 4.0 включена по умолчанию. Для предшествую-
щих версий она выключалась по умолчанию только с MIT-pthreads, потому что
вызов flock () не полностью поддерживается пакетом MIT-pthreads на всех плат-
формах. Это также включено по умолчанию в Linux, так как файловая блокировка
Linux пока недостаточно безопасна. Имейте в виду, что опция —skip-external-
locking не затрагивает функциональности MySQL до тех пор, пока вы запускаете
на машине только один сервер. Просто помните, что надо остановить сервер (или
заблокировать и сбросить соответствующие таблицы) перед запуском myisamchk.
На некоторых системах эта опция обязательна, поскольку внешняя блокировка в
любом случае не работает.
Единственный случай, когда вы не можете использовать —skip-external-
locking, это если вы запускаете несколько экземпляров сервера MySQL (а не кли-
ента) для работы с одними и теми же данными, или если вы запускаете myisamchk
для проверки (но не восстановления) таблицы, не указывая серверу предвари-
тельно сбросить и заблокировать эту таблицу.
Вы можете по-прежнему применять LOCK TABLES/UNLOCK TABLES, даже если ис-
пользуется —skip-external-locking.
6.5. Оптимизация сервера MySQL 449

6.5.2. Настройка параметров сервера


Вы можете определить размеры буферов по умолчанию, которые будет использовать
сервер mysqld, следующей командой (для версий до MySQL 4.1 опустите —verbose):
shell> mysqld —verbose --help
Эта команда генерирует список всех опций mysqld и конфигурируемых системных
переменных. Этот список включает также значения по умолчанию и выглядит примерно
так:
back log current value: 5
bdb_cache_size current value: 1048540
binlog_cache_size current value: 32768
connect timeout current value: 5
delayed insert limit current value: 100
delayed insert timeout current value: 300
delayed_queue_size current value: 1000
flush time current value: 0
interactive timeout current value: 28800
join buffer size current value: 131072
key buffer size current value: 1048540
long_query_time current value: 10
lower case table names current value: 0
max_allowed_packet current value: 1048576
max binlog cache size current value: 4294967295
max connect errors current value: 10
max connections current value: 100
max delayed threads current value: 20
max heap table size current value: 16777216
max join size current value: 4294967295
max_sort_length current value: 1024
max tmp tables current value: 32
max write lock count current value: 4294967295
myisam sort buffer size current value: 8388608
net buffer length current value: 16384
net read timeout current value: 30
net retry count current value: 10
net write timeout current value: 60
read_buffer_size current value: 131072
read_rnd_buffer_size current value: 262144
slow launch time current value: 2
sort buffer current value: 2097116
table cache current value: 64
thread concurrency current value: 10
thread stack current value: 131072
tmp table size current value: 1048576
wait timeout current value: 28800
Если в настоящий момент есть запущенный сервер mysqld, вы можете увидеть, какие
значения системных переменных в нем установлены, подключившись к нему и выпол-
нив оператор:
mysql> SHOW VARIABLES;
450 Глава 6. Оптимизация MySQL

Вы также можете увидеть некоторые статистические и относящиеся к состоянию по-


казатели работающего сервера, выполнив следующее:
mysql> SHOW STATUS;
Системные переменные и информацию о состоянии можно также получить, исполь-
зуя mysqladmin:
shell> mysqladmin variables
shell> mysqladmin extended-status
Полное описание всех системных переменных и переменных состояния приведено в
разделах 4.2.3 и 4.2.4.
MySQL использует алгоритмы, которые очень хорошо масштабируются, поэтому вы
обычно можете запускать его, имея очень мало памяти. Однако, обычно, более высокая
производительность MySQL достигается предоставлением ему большего объема памяти.
При настройке сервера MySQL две наиболее важные переменные - это
k e y b u f f e r s i z e и tablecache. Прежде чем пытаться изменять значение других пере-
менных, вы должны быть уверены в том, что значение этих двух установлено правильно.
Следующие примеры показывают некоторые типичные значения переменных для
различных конфигураций времени исполнения. В этих примерах используется сценарий
mysqld_safe и синтаксис —имя_переменной= значение для установки значения перемен-
ной имя_переменной в значение значение. Этот синтаксис принят в MySQL, начиная с
версии 4.0. При использовании более старых версий, примите во внимание следующие
моменты:
• Используйте safejnysqld вместо raysqld_safe.
• Устанавливайте переменные с использованием синтаксиса --set-variable=
имя_переменной= значение или -0 имя_переменной= значение.
• Переменные, у которых имя оканчивается на _size, возможно, придется специ-
фицировать без _size. Например, старое имя sort__buffer_size выглядело как
sort_buffer. Старым именем для read_buffer_size было sort_buffer. Чтобы
увидеть, какие имена переменных распознает ваш сервер, выдайте команду
mysqld —help.
Если у вас есть, как минимум, 256 Мбайт памяти, много таблиц, и вы хотите полу-
чить максимум производительности при небольшом количестве клиентов, вы должны
использовать примерно следующее:
shell> mysqld_safe —key_buffer_size=64M —table_cache=256 \
--sort_buffer_size=4M — read_buffer_size=lM &
Если у вас только 128 Мбайт памяти и всего несколько таблиц, но вам требуется вы-
полнять большие объемы сортировки, можно использовать что-то вроде этого:
shell> mysqld_safe —key_buffer_size=16M —sort_buffer_size=lM
Если выполняется очень много одновременных подключений, проблемы подкачки
могут возникнуть независимо от того, что mysqld был сконфигурирован на использова-
ние малого объема памяти для каждого соединения, mysqld работает лучше, если у вас
достаточно памяти для всех соединений.
Когда мало памяти и много соединений, попробуйте что-то вроде этого:
shell> mysqld_safe --key_buffer_size=512K —sort_buffer_size=100K \
—read buffer size=100K &
6.5. Оптимизация сервера MySQL 451

или даже этого:


shell> mysqldjsafe --key_buffer_size=512K —sortJbuffer_size=16K \
—table_cache=32 —read_buffer_size=8K \
—netJbuffer_length=lK &
Если вы выполняете операции GROUP BY или ORDER BY на таблицах, размер которых
значительно превышает объем доступной памяти, то должны увеличить значение
read_rnd_buf f e r s i z e для повышения скорости чтения строк после операций сортировки.
После установки MySQL в каталоге support-files содержатся некоторые примеры
файла my.cnf, а именно: my-huge.cnf, my-large.cnf, my-medium.cnf и my-small.cnf. Вы
можете использовать эти файлы в качестве базы при оптимизации вашей системы.
Имейте в виду, что если опции указываются в командной строке mysqld или
mysqld_safe, они остаются в силе только на текущий запуск сервера. Чтобы использо-
вать опции при каждом запуске, поместите их в файл настроек.
Чтобы увидеть эффект от изменения параметров, выполните следующую команду
(для версий, предшествующих MySQL 4.1, не указывайте —verbose):
shell> mysqld —keyJbuffer_size=32M —verbose —help
Значения переменных перечислены в конце вывода. Убедитесь, что опции —verbose
и —help идут последними. В противном случае все опции, указанные после них, не
окажут влияния на вывод.
Информацию о настройке механизма хранения InnoDB можно найти в разделе 9.12.

6.5.3. Как компиляция и компоновка влияют


на скорость MySQL
Большинство следующих тестов производительности выполнялись под Linux, но они
должны дать определенное представление о работе и в других операционных системах и
рабочих окружениях.
Самые быстрые исполняемые программы получаются, если применять статическую
компоновку, указывая - s t a t i c .
В Linux вы получите самый быстрый код, если скомпилируете с помощью рдсс и -03.
Понадобится около 200 Мбайт памяти для компиляции с этой опцией файла
sql_yacc. ее, потому что для gcc/pgcc требуется много памяти, чтобы сделать все функ-
ции встроенными. Вы также должны установить СХХ=дсс перед компиляцией MySQL,
чтобы избежать включения библиотеки libstdc++, которая не нужна. Помните, что с
некоторыми версиями рдсс результирующий код будет работать только с истинными
процессорами Pentium, даже если вы используете опции компилятора, указывающие на
необходимость генерации кода, совместимого со всеми процессорами семейства х586
(такими как AMD).
Используя лучший компилятор и лучший набор опций, вы можете получить 10-30 %
рост производительности приложения. В частности, это так же верно при компиляции
самого сервера MySQL.
Мы тестировали компиляторы Су gnus CodeFusion и Fujitsu, но когда мы это делали,
ни один из них не был настолько свободен от ошибок, чтобы позволить скомпилировать
MySQL с включенной оптимизацией.
Стандартные бинарные дистрибутивы MySQL компилируются с поддержкой всех
наборов символов. Когда вы компилируете его самостоятельно, вы можете включить
452 Глава 6. Оптимизация MySQL

поддержку только необходимых вам наборов символов. Это управляется опцией —with-
charset сценария configure.
Ниже приведен список некоторых замеров, которые мы сделали:
• Если применяется компилятор рдсс и все компилируется с опцией -Об, mysqld ра-
ботает на 1% быстрее, чем при использовании дсс 2.95.2.
• Если применяется динамическая компоновка (без -static), результат под Linux
на 13% медленнее. Помните, что вы можете использовать динамические библио-
теки MySQL для клиентских приложений. Вышесказанное касается сервера, для
которого производительность критична.
• Если вы удаляете отладочную информацию из бинарного кода командой s t r i p
mysqld, результирующий код может стать на 4% быстрее.
• Для подключения клиента к серверу, запущенному на том же хосте, если вы под-
ключаетесь по TCP/IP вместо сокетов Unix, производительность получается на
7,5% медленнее. (В Unix, если вы подключаетесь, указывая имя хоста localhost,
MySQL использует файлы сокетов по умолчанию).
• Подключение по TCP/IP к удаленному серверу, находящемуся на другом хосте, на
8-11% медленнее, чем подключение к локальному серверу, на том же хосте, даже
если применяется сетевой интерфейс Ethernet 100 Мбит/с.
• При запуске нашего набора тестов производительности по защищенному соеди-
нению (когда все данные шифруются внутренней поддержкой SSL), производи-
тельность получается на 55% ниже, чем по незащищенному соединению.
• Если вы компилируете с —with-debug=full, большинство запросов будут выпол-
няться на 20% медленнее. Некоторые запросы могут потребовать значительно
большего времени. Например, тесты производительности MySQL выполняются на
35% медленнее. Если вы используете —with-debug (без =full), замедление соста-
вит только 15%. Для версии mysqld, скомпилированной с —with-debug=full, вы
можете выключить проверку памяти во время выполнения, запустив его с опцией
—skip-safemalloc. Конечный результат в этом случае будет близким к тому, что
получается при конфигурировании компиляции с --with-debug.
• На машине Sun UltraSPARC-lie сервер, скомпилированный Forte 5.0, работает на
4% быстрее, чем собранный с помощью gcc 3.2.
• На Sun UltraSPARC-He сервер, скомпилированный Forte 5.0, работает на 4% бы-
стрее в 32-разрядном режиме, чем в 64-разрядном.
• Компиляция с помощью дсс 2.95.2 для UltraSPARC с опциями -mcpu=v8 -Wa,
-xarch=v8plusa дает на 4% более высокую производительность.
• В Solaris 2.5.1 на однопроцессорной машине с пакетом MIT-pthreads MySQL ра-
ботает на 8-12% медленнее, чем со встроенной поддержкой потоков Solaris. При
большей загрузке процессора разница будет еще больше.
• Компиляция в Linux-x86 с использованием компилятора дсс без указателей
фреймов (-fomit-frame-pointer или -fomit-frame-pointer -ffixed-ebp) делает
mysqld на 1-4% быстрее.
Бинарный дистрибутив MySQL для Linux, который поставляется компанией MySQL
АВ, скомпилирован рдсс. Мы собираемся вернуться обратно к дсс из-за ошибки в рдсс,
6.5. Оптимизация сервера MySQL 453

которая приводит к невозможности генерации кода для процессоров AMD. Мы продол-


жим использовать дсс до тех пор, пока ошибка не будет устранена. Между тем, если у
вас машина с процессором, отличным от AMD, вы можете получить более быстрый код,
компилируя с помощью рдсс. Стандартный бинарный дистрибутив MySQL для Linux
компонуется статически, чтобы сделать его быстрее и более переносимым.

6.5.4. Как MySQL использует память


В следующем списке представлены способы, по которым сервер mysqld использует
память. Где это применимо, имя системной переменной существенно для использования
памяти, которого она касается.
• Буфер ключей (переменная key_buffer_size) раздельно используется всеми по-
токами, другие буферы, используемые сервером, выделяются по мере необходи-
мости. См. раздел 6.5.2.
• Каждое подключение использует некоторое специфичное для потока пространство:
• Стек (по умолчанию 64 Кбайт, переменная thread_stack).
• Буфер подключения (переменная net_buf f er_length).
• Буфер результата (переменная result_buf fer_length).
Буфер подключения и буфер результата динамически увеличиваются при необхо-
димости, вплоть до max_allowed_packet. Пока выполняется запрос, копия теку-
щей строки запроса также распределяется в памяти.
• Все потоки разделяют одну базовую память.
• Только сжатые таблицы ISAM и MylSAM отображаются в память. Это связано с тем,
что 32-разрядное пространство памяти в 4 Гбайт недостаточно для большинства
крупных таблиц. Когда системы с 64-разрядным адресным пространством станут
более распространенными, возможно, мы добавим общую поддержку отображе-
ния памяти.
• Каждый запрос, который выполняет последовательное сканирование таблицы,
распределяет буфер чтения (переменная read_rnd_buf fer_size).
• Все соединения выполняются за один проход, и большинство соединений могут
быть сделаны даже без использования временной таблицы. Большинство времен-
ных таблиц размещаются в памяти (memory-based, HEАР-tables). Временные таб-
лицы с большой длинной записи (вычисляемой как сумма длин столбцов) либо
содержащие столбцы типа BLOB сохраняются на диске.
Одна проблема, которая имела место до MySQL 3.23.2, состояла в том, что внут-
ренние таблицы, размещенные в памяти, превышали по размеру tmp_table_size,
что приводило к ошибке "The t a b l e имя^таблицы is f u l l " ("Таблица
имя_пгаблщы переполнена"). Начиная с версии 3.23.2, эта ситуация обрабатыва-
ется автоматически, путем замены таблицы в памяти на таблицу My ISAM на диске.
Для того чтобы обойти эту проблему в более старых версиях сервера, можно уве-
личить размер временной таблицы, установив опцию tmp_table_size для mysqld
или установив SQL-опцию SQLBIGTABLES в клиентской программе.
В MySQL 3.20 максимальный размер временной таблицы определяется как
record_buffer * 16. Если вы используете эту версию, то должны увеличить зна-
чение record_buffer. Вы также можете запустить mysqld с опцией —big-tables,
454 Глава 6. Оптимизация MySQL

чтобы всегда сохранять временные таблицы на диске. Однако это скажется на


скорости многих сложных запросов.
• Большинство запросов, выполняющих сортировку, размещают буфер сортировки
и от нуля до двух временных файлов, в зависимости от размера результирующего
набора. См. раздел А.4.4.
• Почти все анализы и вычисления выполняются в локальной памяти. Для мелких
элементов каких-либо накладных расходов, связанных с памятью, не возникает,
поэтому удается избежать обычного медленного выделения и освобождения па-
мяти. Память выделяется только для неожиданно больших строк. Это делается
вызовами malloc () и free ().
• Для каждой открываемой таблицы My ISAM и ISAM индексный файл открывается
один раз, а файл данных - один раз для каждого из параллельных потоков, кото-
рые обслуживают клиентские соединения. Для каждого параллельного потока вы-
деляется память под структуру таблицы, структуры каждой из столбцов и буфер
размером 2 * N (где N - максимальная длина строки, не считая столбцов BLOB).
Столбец типа BLOB требует от пяти до восьми байт, плюс длина данных BLOB. Ме-
ханизмы хранения ISAM и My ISAM поддерживают один дополнительный буфер
строки для внутреннего использования.
• Для каждой таблицы, содержащей столбец BLOB, буфер увеличивается динамиче-
ски, чтобы читать большие значения BLOB. Если вы сканируете таблицу, размер
буфера будет настолько большим, чтобы поместилось наибольшее значение BLOB.
• Управляющие структуры для всех находящихся в использовании таблиц сохра-
няются в кэше и обрабатываются по алгоритму FIFO. По умолчанию кэш имеет
64 позиции. Если таблица используется двумя работающими потоками одновре-
менно, кэш содержит две позиции для этой таблицы. См. раздел 6.4.8.
• Оператор FLUSH TABLES или команда mysqladmin flush-tables закрывают все
таблицы, которые не используются, и помечают к закрытию все используемые
таблицы, когда работающие в настоящий момент потоки завершатся. Это эффек-
тивно освобождает большую часть используемой памяти.
Программа ps и другие, показывающие состояние системы, могут сообщать, что
mysqld использует много памяти. Это может быть вызвано стеками потоков на разных
адресах памяти. Например, версия ps от Solaris считает неиспользуемую память между
стеками как используемую. В этом можно убедиться, проверив размер доступного файла
подкачки с помощью команды swap -s. Мы тестировали mysqld с использованием раз-
личных детекторов утечки памяти (как коммерческих, так и с открытым исходным ко-
дом), поэтому утечек памяти там быть не должно.

6.5.5. Как MySQL использует DNS


Когда новый клиент подключается к mysqld, он порождает новый поток, чтобы об-
служить запрос. Этот поток первым делом проверяет, находится ли имя хоста в кэше
имен хостов. Если нет, он пытается преобразовать имя хоста:
• Если операционная система поддерживает безопасные к потокам вызовы
gethostbyaddr_r () и gethostbyname_r (), то поток использует их для преобразо-
вания имени хоста.
6.6. Вопросы использования дисков 455

• Если эти вызовы не поддерживаются, поток блокирует семафор и вызывает вме-


сто них gethostbyaddr () и gethostbyname (). В этом случае никакой другой поток
не может преобразовывать имена хостов до тех пор, пока первый поток не раз-
блокирует семафор.
Вы можете отключить поиск имен хостов DNS, запустив сервер с опцией —skip-
host-cache. Однако в этом случае вы сможете использовать только IP-адреса в таблицах
привилегий MySQL. Если система DNS очень медленная, а хостов много, более высокой
производительности можно добиться либо отключением поиска в DNS с помощью оп-
ции —skip-name-resolve, либо увеличением значения HOST_CACHE_SIZE (по умолчанию
128) и перекомпиляцией mysqld.
Можно отключить кэш имен хостов, запустив сервер с опцией —skip-host-cache.
Чтобы очистить кэш имен хостов, выполните оператор FLUSH HOSTS или команду
mysqladmin flush-hosts.
Если вы хотите полностью запретить подключения по TCP/IP, запустите mysqld с оп-
цией —skip-networking.

6.6. Вопросы использования дисков


• Доступ к диску - это серьезное узкое место в контексте производительности. Эта
проблема становится более ощутимой по мере того, как объемы хранимых данных
начинают расти, что приводит к тому, что становится невозможным эффективное
кэширование. Для больших баз данных, в которых доступ осуществляется более-
менее случайно, вы можете быть уверены, что вам нужна, по крайней мере, одна
операция доступа к диску для чтения и несколько - для записи. Чтобы минимизи-
ровать эту проблему, используйте диски с малым временем доступа.
• Увеличивайте количество доступных физических дисков (и, таким образом, сни-
жайте нагрузку, связанную с позиционированием), либо вводя символические
ссылки на файлы на других дисках, либо за счет применения чередования (раз-
биения на полосы) дисков:
• Использование символических ссылок. Это означает, что для таблиц My ISAM
файлы данных и/или индексов перемещаются на другой диск, а в каталоге их
обычного расположения создаются символические ссылки, указывающие на
их новое местоположение. Это улучшает время доступа и чтения, предполагая,
что диск не используется для других целей. См. раздел 6.6.1.
• Чередование (разбиение на полосы). Чередование означает, что вы имеете
много дисков и помещаете первый блок на первый диск, второй блок - на вто-
рой диск и N-H блок на N-й диск (N- общее количество дисков). Это означает,
что если ваш нормальный размер данных меньше, чем размер полосы чередо-
вания (или абсолютно совпадает), то вы получите гораздо лучшую производи-
тельность. Этот метод очень зависит от операционной системы и ширины по-
лосы чередования, поэтому протестируйте свое приложение с разными значе-
ниями ширины. См. раздел 6.1.5.
Разница в скорости при чередовании очень зависит от параметров. В зависи-
мости от того, как вы установите параметры чередования и количество дисков,
вы можете получить сильно отличающиеся результаты. Для оптимизации вам
нужно выбирать между случайным и последовательным доступом.
456 Глава 6. Оптимизация MySQL

• Для целей надежности может возникнуть желание использовать массив RAID 0+1
(чередование плюс зеркальное отображение), но в этом случае вам понадобится
2*N физических устройств, чтобы иметь N устройств для данных. Это, вероятно,
наилучший выбор, если вы располагаете соответствующими финансовыми сред-
ствами. Однако вы можете также инвестировать их в программное обеспечение
управления дисковыми томами, для повышения эффективности.
• Хорошее решение - варьировать уровень RAID в соответствии с тем, насколько
критичны данные. Например, разместите маловажные данные, которые можно ре-
генерировать, на диск RAID 0, но сохраните действительно важные данные, такие
как информация хоста и протоколы, на диске RAID 0+1 или RAID N. Применение
RAID N может стать проблемой, если у вас много операций записи, из-за времени,
необходимого для обновления битов четности.
• В Linux вы можете получить намного более высокую производительность, ис-
пользуя hdparm для конфигурирования вашего дискового интерфейса (До 100%
под нагрузкой не является чем-то необычным.) Следующие параметры hdparm
должны быть достаточно хороши для MySQL и, предположительно, для многих
других приложений:
hdparm -m 16 -d 1
Помните, что производительность и надежность при использовании этой команды
зависит от существующего оборудования, поэтому мы настоятельно советуем
всесторонне протестировать систему после применения команды hdparm. Оз-
накомьтесь с man-страницами, посвященными hdparm, чтобы получить более под-
робную информацию. Если hdparm применять неосмотрительно, результатом мо-
жет быть повреждение файловой системы, поэтому сделайте резервные копии пе-
ред тем, как будете экспериментировать!
• Вы также можете установить параметры файловой системы, которую использует
база данных:
Если вам не нужно знать, когда осуществлялся доступ к файлам в последний раз
(что на самом деле не очень-то нужно для сервера баз данных), вы можете смон-
тировать файловую систему с опцией -о noatime. Это позволит пропускать об-
новления последнего времени доступа в узлах inode файловой системы, что со-
кратит количество обращений к диску.
На многих операционных системах вы можете настроить асинхронное обновление
файловой системы, монтируя ее с опцией -о async. Если ваш компьютер доста-
точно стабилен, это даст более высокую производительность, без необходимости
приносить в жертву надежность. (Этот флаг в Linux применяется по умолчанию.)

6.6.1. Использование символических ссылок


Вы можете перемещать таблицы и базы данных из каталога данных в другие места и
заменять их символическими ссылками, указывающими на их новое местоположение.
Потребность в этом может возникнуть, например, если необходимо переместить базу
данных в файловую систему, в которой больше свободного места, или повысить ско-
рость за счет разнесения таблиц по разным дискам.
Рекомендуемый способ сделать это - просто установить символическую ссылку на
базу данных на другом диске. Устанавливать символические ссылки на отдельные таб-
лицы имеет смысл только в крайних случаях.
б.б. Вопросы использования дисков 457

6.6.1.1. Использование символических ссылок на базы данных в Unix


В Unix для установки символической ссылки на базу данных первым делом надо соз-
дать каталог на некотором диске, где вы имеете достаточно свободного пространства,
после чего создать символическую ссылку на этот каталог из каталога данных MySQL.
shell> xnkdir /drl/databases/test
shell> In -s /drl/databases/test /путь/к/'каталогу_данных
MySQL не поддерживает ссылки одного каталога сразу на множество баз данных. За-
мена каталога данных на символическую ссылку работает хорошо до тех пор, пока вы не
создаете ссылок между базами. Предположим, что у вас есть база данных dbl в каталоге
данных MySQL, и вы создаете символическую ссылку db2, которая указывает на dbl:
shell> cd /путь/к/'каталогу_данных
shell> In -s dbl db2
Теперь для каждой таблицы t b l a в базе данных dbl появляется соответствующая
таблица tbl_a в базе данных db2. Если один клиент обновляет dbl.tbl_a, а другой -
db2. tbl_a, возникнут проблемы.
Если вам действительно нужно так сделать, вы можете изменить один из исходных
файлов. Файл, который необходимо модифицировать, зависит от вашей версии MySQL.
Для MySQL 4.0 и выше обратите внимание на следующий фрагмент кода в файле
mysys/my_symlink.c:
if (!(MyFlags & MY_RESOLVE_LINK) | |
(ilstat(filename,&stat_buff) && S_ISLNK(stat_buff.stjnode)))
Для версий MySQL, предшествующих 4.0, найдите в файле mysys/mf_format.c сле-
дующий фрагмент:
if (flag & 32 | | (Ilstat(to,&stat_buff) && S_ISLNK(stat_buff.stjnode)))
В обоих случаях замените это на такой код:
if (1)
В Windows можно использовать внутренние символические ссылки на каталоги,
скомпилировав MySQL с ключом -DUSESYMDIR. Это позволит размещать разные базы
данных на разных дисках. См. раздел 6.6.3.1.

6.6.1.2. Использование символических ссылок на таблицы в Unix


До версии MySQL 4.0 не рекомендовалось применять символические ссылки на таб-
лицы, если только вы не проявляли исключительную аккуратность в отношении к ним.
Проблема состояла в том, что если вы запускали ALTER TABLE, REPAIR TABLE или
OIPTIMIZE TABLE на таблицах, доступ к которым осуществлялся через символические
ссылки, эти ссылки удалялись и заменялись исходными файлами. Это происходило по-
тому, что эти операторы работают, создавая временные файлы в каталоге данных и за-
тем заменяя исходные файлы этими временными файлами по окончании работы.
Вы не должны символически связывать таблицы в системах, которые не поддержи-
вают полноценно работающего вызова realpath (). (По крайней мере, Linux и Solaris
поддерживают realpath ().) Вы можете проверить, поддерживает ли ваша система сим-
волические ссылки, выполнив оператор SHOW VARIABLES LIKE 'have_symlink'.
В версии MySQL 4.0 символические ссылки полноценно поддерживаются только для
таблиц My ISAM. Для других типов таблиц вы, возможно, столкнетесь со странными про-
458 Глава 6. Оптимизация MySQL

блемами, если попытаетесь использовать символические ссылки на файлы в операцион-


ной системе с любым из приведенных ранее операторов.
Управление символическими ссылками для таблиц My ISAM осуществляется следую-
щим образом:
• В каталоге данных у вас всегда есть файл определения таблиц, файл данных и ин-
дексный файл. Файл данных и индексный файл можно перемещать куда угодно и
в каталоге данных подменять символическими ссылками. С другой стороны, файл
определений - нельзя.
• Вы можете устанавливать символические ссылки на файл данных и индексный
файл в разные каталоги независимо друг от друга.
• Установка символических ссылок может выполняться вручную из командной
строки командой In -s, если mysqld не запущен. Посредством SQL вы можете из-
вестить сервер о необходимости установки символической ссылки, используя оп-
ции DATA DIRECTORY И INDEX DIRECTORY оператора CREATE TABLE.
• myisamchk не заменяет символическую ссылку файлом данных или файлом индек-
са. Она работает непосредственно с файлом, на который указывает ссылка. Все
временные файлы создаются в каталоге, где находятся файл данных или индекс-
ный файл.
• Когда вы удаляете таблицу, которая использует символическую ссылку, уничто-
жается как ссылка, так и сам файл. Это серьезная причина для того, чтобы не за-
пускать mysqld от имени root, или предоставлять пользователям право записи в
каталоги данных MySQL.
• Если вы переименовываете таблицу с помощью оператора ALTER TABLE...
RENAME и не перемещаете таблицу в другой каталог, символические ссылки в ката-
логе данных переименовываются, а сами файлы данных и индексов переименовы-
ваются соответственно.
• Если вы применяете ALTER TABLE... RENAME для перемещения таблицы в другую
базу данных, таблица перемещается в другой каталог данных. Старые символиче-
ские ссылки и файлы, на которые они указывают, удаляются. Другими словами,
новая таблица не будет связана символической ссылкой.
• Если вы не пользуетесь символическими ссылками, то должны применять опцию
—skip-symbolic-links с mysqld, дабы гарантировать, что никто не сможет ис-
пользовать mysqld для удаления или переименования файла вне каталога данных.
Оператор SHOW CREATE TABLE не сообщал о том, что таблица имела символические
ссылки, вплоть до версии MySQL 4.0.15. Это также верно для утилиты mysqldump, кото-
рая использовала SHOW CREATE TABLE для генерации оператора CREATE TABLE.
Ниже перечислены операции над символическими ссылками таблиц, которые пока не
поддерживаются:
• ALTER TABLE игнорирует ОПЦИИ DATA DIRECTORY И INDEX DIRECTORY.
• BACKUP TABLE и RESTORE TABLE не воспринимают символические ссылки.
• Файл . f rm никогда не должен быть символической ссылкой (как уже упомина-
лось, только файлы данных и индексов могут быть символическими ссылками).
Попытки сделать это (например, чтобы создать синонимы) приведет к некоррект-
ным результатам. Предположим, что у вас есть база dbl в каталоге данных
6.6. Вопросы использования дисков 459

MySQL, таблица t b l l в этой базе, а в каталоге dbl вы создаете символическую


ссылку tbl2, указывающую на t b l l :
shell> cd /путь/к/каталогу_данных/6Ы
shell> In -s tbll.frm tbl2.frm
shell> In -s tbll.MYD tbl2.MYD
shell> In -s tbll.MYI tbl2.MYI
Если один поток читает d b l . t b l l , а другой обновляет dbl.tbl2, возникнут про-
блемы:
• Кэш запросов будет сбит с толку (он будет считать, что таблица t b l l не об-
новлялась, поэтому вернет устаревший результат).
• Операторы ALTER на таблице tbl2 также завершатся неудачей.

6.6.1.3. Использование символических ссылок на базы данных в Windows


Начиная с MySQL 3.23.16, серверы mysqld-max и mysqld-max-nt для Windows компи-
лируются с опцией -DUSESYMDIR. Это позволяет поместить каталог данных на другой
диск, установив символическую ссылку на него. Это похоже на символические ссылки в
Unix, хотя процедура их определения отличается.
Начиная с версии MySQL 4.0, символические ссылки по умолчанию разрешены. Если
они не нужны, можете отключить их поддержку в конфигурационном файле через оп-
цию skip-symbolic-links:
[mysqld]
skip-symbolic-links
До версии MySQL 4.0 символические ссылки были выключены по умолчанию. Что-
бы включить их, потребуется поместить в конфигурационный файл my.cnf или my.ini
следующие строки:
[mysqld]
symbolic-links
В среде Windows вы создаете символическую ссылку на базу данных MySQL, созда-
вая файл в каталоге данных, содержащий путь на целевой каталог. Этот файл должен
называться имя_базы^_данных. sym, где имя_базы_данных — имя базы данных.
Предположим, что каталог данных MySQL находится в C:\mysql\data, и вы хотите
иметь базу данных foo, расположенную в D: \data\foo. Создайте символическую ссылку
следующим образом:
1. Убедитесь, что каталог D:\data\foo существует или при необходимости создайте
его. Если у вас уже есть подкаталог базы данных foo в каталоге данных, вы долж-
ны переместить его в D:\data. В противном случае символическая ссылка будет
недействительной. Во избежание проблем, при перемещении этого каталога сер-
вер не должен функционировать.
2. Создайте файл С: \mysql\data\foo. sym, который содержит путь D: \data\foo\.
После этого все таблицы, созданные в базе данных foo, будут созданы в каталоге
D:\data\foo\. Имейте в виду, что символическая ссылка не будет использоваться, если
каталог с именем этой базы данных существует в каталоге данных MySQL.
7

Клиентские программы
и утилиты MySQL

С уществует множество различных клиентских программ MySQL, предназначенных


для подключения к серверу, доступа к базам данных и выполнения администра-
тивных задач. Доступны также другие утилиты, которые не взаимодействуют с серве-
ром, но выполняют операции, имеющие отношение к MySQL.
В этой главе приводится краткий обзор этих программ вместе с детальными описа-
ниями каждой из них. Рассказывается, как запускать эти программы, и какие опции они
понимают. В главе 3 можно найти общую информацию о запуске программ и передаче
им необходимых опций.

7.1. Обзор сценариев иутилит


клиентской стороны
В следующем списке кратко представлены клиентские программы и утилиты
MySQL:
• myisampack. Утилита сжатия таблиц MylSAM для создания более компактных таб-
лиц, доступных только по чтению. См. раздел 7.2.
• mysql. Инструмент командной строки для интерактивного ввода SQL-операторов
или выполнения их из файла в пакетном режиме. См. раздел 7.3.
• mysqlaccess. Сценарий, проверяющий права доступа пользователя к хосту и базе
данных.
• mysqladmin. Клиентская программа, выполняющая административные операции,
такие как создание и уничтожение баз данных, перезагрузка таблиц грантов, вы-
грузка таблиц на диск и повторное открытие журнальных файлов. См. раздел 7.4.
• mysqlbinlog. Утилита чтения операторов из бинарного журнала. Список выпол-
няемых операторов, содержащийся в бинарном журнале, может быть использован
для восстановления после аварий. См. раздел 7.5.
• mysqlcc. Клиент, предоставляющий графический интерфейс для взаимодействия с
сервером. См. раздел 7.6.
• mysql check. Клиент обслуживания таблиц, предназначенный для проверки, вос-
становления, анализа и оптимизации таблиц. См. раздел 7.7.
7.2. myisampack — генератор сжатых таблиц MySQL, доступных только для чтения 461

• mysqldump. Клиентская программа для экспорта дампа базы данных MySQL в


файл в виде SQL-операторов или текстового файла с разделителями-табуляциями.
Усовершенствованная свободно распространяемая программа Игоря Романенко
(Igor Romanenko). См. раздел 7.8.
• mysqlhotcopy. Утилита, выполняющая быстрое резервное копирование таблиц
My ISAM или ISAM при работающем сервере. См. раздел 7.9.
• mysqlimport. Клиентская программа, импортирующая текстовые файлы в соот-
ветствующие таблицы с применением LOAD DATA INFILE. См. раздел 7.10.
• mysqlshow. Клиентская программа, выводящая информацию о базах данных, таб-
лицах, столбцах и индексах. См. раздел 7.11.
• p e r r o r . Утилита, отображающая описание кодов системных ошибок или ошибок
MySQL. См. раздел 7.12.
• r e p l a c e . Утилита замены строк в файлах или в стандартном потоке ввода. См.
раздел 7.13.
Каждая программа MySQL принимает множество различных опций. Однако все про-
граммы распознают опцию - - h e l p , которую можно использовать для получения полного
описания всех опций программы. Для примера попробуйте ввести mysql — h e l p .
Клиентские программы MySQL, которые взаимодействуют с сервером, используя
библиотеку m y s q l c l i e n t , имеют дело со следующими переменными окружения:
MYSQL_UNIX_PORT Значение по умолчанию имени файла сокета Unix;
используется для подключения локальных клиентов.
MYSQL_TCP_PORT Значение по умолчанию номера порта TCP/IP.
MYSQL_PWD Пароль по умолчанию.
MYSQL_DEBUG Опции трассировки во время отладки.
TMPDIR Каталог временных файлов.
П р и м е н е н и е MYSQL_PWD небезопасно. С м . раздел 4.5.6.
В ы м о ж е т е переопределить значения о п ц и й п о у м о л ч а н и ю и л и опций, у к а з а н н ы х в
п е р е м е н н ы х окружения д л я всех с т а н д а р т н ы х п р о г р а м м , задав и х в ф а й л е к о н ф и г у р а ц и и
или в к о м а н д н о й строке. С м . раздел 3.3.

7.2. myisampack — генератор сжатых таблиц


MySQL, доступных только для чтения
Утилита myisampack сжимает таблицы MylSAM. Она работает, сжимая каждый столбец
таблицы по отдельности. Обычно myisampack сжимает файлы данных на 40-70%.
Когда таблица используется позже, информация, необходимая для распаковки столб-
цов, считывается в память. Это существенно увеличивает производительность при дос-
тупе к отдельным записям, поскольку приходится распаковывать только одну запись, а
не значительно больший дисковый блок, как это делает Stacker в среде MS-DOS.
MySQL использует функцию mmap (), где это возможно, чтобы выполнить отображе-
ние в память сжатых таблиц. Если mmap () не работает, MySQL возвращается обратно к
нормальным файловым операциям чтения/записи.
462 Глава 7. Клиентские программы и утилиты MySQL

Похожая утилита, pack_isam, сжимает таблицы ISAM. Поскольку формат таблиц ISAM
считается устаревшим, в этом разделе описывается только myisampack, но основные
приемы работы с myisampack подходят также и для packisam, если иное не оговорено
специально.
Следует отметить такие моменты:
• Если сервер mysqld был запущен с опцией —skip-external-locking, не стоит за-
пускать myisampack в отношении таблицы, которую сервер может обновлять од-
новременно с процессом упаковки.
• После упаковки таблицы она становится доступной только для чтения. В общем,
так и было задумано (например, для работы со сжатыми таблицами на компакт-
диске). Обеспечение возможности записи в сжатые таблицы есть в наших планах,
но имеет низкий приоритет.
• myisampack может сжимать столбцы типа TEXT и BLOB. Старая утилита pack_isam
делать это не может.
Запуск myisampack выглядит следующим образом:
shell> myisampack [опции] имя_файла . . .
Каждое имя файла должно быть именем индексного файла (.MYI). Если вы находи-
тесь не в каталоге базы данных, потребуется указать полный путь к файлу. Допускается
не указывать расширение .MYI.
myisampack поддерживает следующие опции:
• —help, -?. Выводит страницу справки и завершает работу.
• --backup, -b. Создает резервную копию данных таблицы под именем
имя_таблицы. OLD.
• —debug [=опции_отладки], -# [опции_отладки]. Записывает журнал отладки.
Обычно строка опции_отладки имеет формат ' d: t :о,имя_файла'.
• —force, -f. Создает упакованную таблицу, даже если она получается больше, чем
исходная, или же найден временный файл, оставшийся от предыдущего запуска
myisampack. (myisampack создает временный файл с именем имя_таблицы.ИШ во
время сжатия таблицы. Если прервать работу myisampack, временный файл может
остаться на диске.) Обычно myisampack завершается с сообщением об ошибке, ес-
ли обнаруживает, что файл имя_таблицы.TMD не удален. С опцией —force упаков-
ка выполняется в любом случае.
• —-}о±п=имя_болыпой_таблицы, -j имя_большой_таблицы. Соединяет все таблицы,
перечисленные в командной строке, в одну таблицу имя_болыпой_таблицы. Все
таблицы, которые нужно соединить таким образом, должны иметь идентичную
структуру (одинаковые имена и типы столбцов, одинаковые индексы и так далее).
• —packlength=#, -р #. Указывает длину адреса записи в байтах. Значением долж-
но быть 1, 2 или 3. myisampack сохраняет все записи с длиной указателей в 1, 2
или 3 байта. В большинстве нормальных случаев myisampack может определить
правильное значение длины до начала упаковки файла, но в процессе может об-
наружить, что допустимо использовать меньшее значение. В этом случае
myisampack выводит сообщение об этом, чтобы следующий раз, когда вы будете
упаковывать этот файл, вы смогли использовать более короткую длину указателя.
7.2. myisampack — генератор сжатых таблиц MySQL, доступных только для чтения 463

• —silent, -s. Режим минимального количества сообщений. Выводит в выходной


поток только сообщения об ошибках, если они возникают.
• —test, -t. He выполняет упаковку таблицы, а только тестирует ее.
• —tmp_diг=луть, -Т путь. Использует указанный каталог как местонахождение
для временных файлов.
• —verbose, -v. Режим расширенных сообщений. Выводит информацию о ходе
операции упаковки и ее результатах.
• --version, -V. Выводит информацию о версии и завершает работу.
• —wait, -W. Ждет и повторяет попытки обработать таблицу, которая в данный мо-
мент занята. Если сервер mysqld был запущен с опцией —skip-external-locking,
не стоит запускать myisampack для таблицы, которая может обновляться сервером.
Представленная ниже последовательность команд иллюстрирует типичный сеанс
упаковки таблиц.
shell> Is -I station.*
-rw-rw-r— 1 monty my 994128 Apr 17 19:00 station.MYD
-rw-rw-r— 1 monty my 53248 Apr 17 19:00 station.MYI
-rw-rw-r— 1 monty my 5767 Apr 17 19:00 station.frm
shell> myisamchk - d w station
MylSAM file: station
Isam-version: 2
Creation time: 1996-03-13 10:08:58
Recover time: 1997-02-02 3:06:43
Data records: 1192 Deleted blocks: 0
Datafile parts: 1192 Deleted data: 0
Datafile pointer (bytes): 2 Keyfile pointer (bytes): 2
Max datafile length: 54657023 Max keyfile length: 33554431
Recordlength: 834
Record format: Fixed length
table description:
Key Start Len Index Type Root Blocksize Rec/key
1 2 4 unique unsigned long 1024 1024 1
2 32 30 multip. text 10240 1024 1
Field Start Length Type
1 1 1
2 2 4
3 6 4
4 10 1
5 11 20
6 31 1
7 32 30
8 62 35
9 97 35
10 132 35
11 167 4
12 171 16
13 187 35
464 Глава 7. Клиентские программы и утилиты MySQL

14 222 4
15 226 16
16 242 20
17 262 20
18 282 20
19 302 30
20 332 4
21 336 4
22 340 1
23 341 8
24 349 8
25 357 8
26 365 2
27 367 2
28 369 4
29 373 4
30 377 1
31 378 2
32 380 8
33 388 4
34 392 4
35 396 4
36 400 4
37 404 1
38 405 4
39 409 4
40 413 4
41 417 4
42 421 4
43 425 4
44 429 20
45 449 30
46 479 1
47 480 1
48 481 79
49 560 79
50 639 79
51 718 79
52 797 8
53 805 1
54 806 1
55 807 20
56 827 4
57 831 4
shell> myisampack station.MYI
Compressing station.MYI: (1192 records)
- Calculating statistics
normal: 20 empty-space: 16 empty-zero: 12 empty-fill: 11
pre-space: 0 end-space: 12 table-lookups: 5 zero: 7
Original trees: 57 After join: 17
- Compressing file
7.2. myisampack - генератор сжатых таблиц MySQL, доступных только для чтения 465
87.14%
Remember to run myisamchk -rq on compressed tables
shell> Is -1 station.*
-rw-rw-r— 1 monty my 127874 Apr 17 19:00 station.MYD
-rw-rw-r— 1 monty my 55296 Apr 17 19:04 station.MYI
-rw-rw-r— 1 monty my 5767 Apr 17 19:00 station.frm
shell> myisamchk - d w station
MylSAM file: station
Isam-version: 2
Creation time 1996-03-13 10:08:58
Recover time: 1997-04-17 19:04:26
Data records: 1192 Deleted blocks: 0
Datafile parts: 1192 Deleted data: 0
Datafile pointer (bytes): 3 Keyfile pointer (bytes): 1
Max datafile length: 16777215 Max keyfile length: 131071
Recordlength: 834
Record format: Compressed
table description:
Key Start Len Index Type Root Blocksize Rec/key
1 2 4 unique unsigned long 10240 1024 1
2 32 30 multip.text 54272 1024 1
Field Start Length Type Huff tree Bits
1 1 1 constant 1 0
2 2 4 zerofill(l) 2 9
3 6 4 no zeros, zerofill(l) 2 9
4 10 1 3 9
5 11 20 table-lookup 4 0
6 31 1 3 9
7 32 30 no endspace, not always 5 9
8 62 35 no endspace, not always, no empty 6 9
9 97 35 no empty 7 9
10 132 35 no endspace, not always, no empty 6 9
11 167 4 zerofill(l) 2 9
12 171 16 no endspace, not_always, no empty 5 9
13 187 35 no endspace, not always, no empty 6 9
14 222 4 zerofill(l) 2 9
15 226 16 no endspace, not_always, no empty 5 9
16 242 20 no endspace, not always 8 9
17 262 20 no endspace, no empty 8 9
18 282 20 no endspace, no empty 5 9
19 302 30 no endspace, no empty 6 9
20 332 4 always zero 2 9
21 336 4 always zero 2 9
22 340 1 3 9
23 341 8 table-lookup 9 0
24 349 8 table-lookup 10 0
25 357 8 always zero 2 9
26 365 2 2 9
27 367 2 no zeros, zerofill(l) 2 9
28 369 4 no zeros, zerofill(l) 2 9
466 Глава 7. Клиентские программы и утилиты MySQL

29 373 4 table-lookup 11 0
30 377 1 3 9
31 378 2 no zeros, zerofill(l) 2 9
32 380 8 no zeros 2 9
33 388 4 always zero 2 9
34 392 4 table-lookup 12 0
35 396 4 no zeros, zerofill(l) 13 9
36 400 4 no zeros, zerofill(l) 2 9
37 404 1 9

Csl
38 405 4 no zeros 2 9
39 409 4 always zero 2 9
40 413 4 no zeros 2 9
41 417 4 always zero 2 9
42 421 4 no zeros 2 9
43 425 4 always zero 2 9
44 429 20 no empty 3 9
45 449 30 no empty 3 9
46 479 1 14 4
47 480 1 14 4
48 481 79 no endspace, no empty 15 9
49 560 79 no empty 2 9
50 639 79 no empty 2 9
51 718 79 no endspace 16 9
52 797 8 no empty 2 9
53 805 1 17 1
54 806 1 3 9
55 807 20 no empty 3 9
56 827 4 no zeros, zerofill(2) 2 9
57 831 4 no zeros, zerofill(l) 9
Csl

myisampack выводит информацию следующего рода:


• normal. Количество столбцов, для которых не выполняется никакой дополнитель-
ной упаковки.
• empty-space. Количество столбцов, содержащих только пробелы; это занимает 1 бит.
• empty-zero. Количество столбцов, содержащих только двоичные нули; это зани-
мает 1 бит.
• empty-fill. Количество целочисленных столбцов, которые не занимают диапазон
байтов, отведенных их типу; они сужаются до более компактного типа. Например,
столбец BIGINT (восемь байт) может храниться как TINYINT (один байт), если все
хранящиеся в ней значения находятся в диапазоне от-128 до 127.
• pre-space. Количество десятичных столбцов, которые хранятся с ведущими про-
белами. В этом случае каждое значение будет содержать информацию о количе-
стве ведущих пробелов.
• end-space. Количество столбцов, имеющих завершающие пробелы. В этом случае
каждое значение будет хранить информацию о количестве таких пробелов.
• table-lookup. Столбцы, содержащие только небольшое количество уникальных
значений. Перед сжатием Хаффмана (Huffman) преобразуются к типу ENUM.
• zero. Количество столбцов, в которых все значения равны нулю.
7.3. Инструмент командной строки mysql 467

• Original trees. Начальное количество деревьев Хаффмана.


• After join. Количество уникальных деревьев Хаффмана, оставшееся после объе-
динения деревьев для экономии места заголовков.
После того, как таблица была сжата, myisamchk -dvv выводит дополнительную ин-
формацию о каждом столбце:
• Туре. Тип столбца. Может принимать одно их следующих значений:
• constant. Все строки имеют одинаковые значения.
• no endspace. He хранить завершающие пробелы.
• no endspace, not_always. He хранить завершающие пробелы и не выполнять
сжатие завершающих пробелов для всех значений.
• no endspace, no empty. He хранить завершающие пробелы. Не хранить пус-
тые значения.
• table-lookup. Столбцы были преобразованы к типу ENUM.
• z e r o f i l l ^ ) . Самые старшие л байт в значениях равны нулю и не сохраняются.
• no zeroes. He хранить нули.
• always zero. Нулевые значения хранятся, занимая один бит.
• Huff tree. Количество деревьев Хаффмана, ассоциируемых со столбцом.
• Bits. Количество бит, используемых деревом Хаффмана.
После того, как вы запустили myisampack, вы должны запустить myisamchk, чтобы
пересоздать индексы. Одновременно вы можете отсортировать блоки индексов и со-
брать статистику, необходимую оптимизатору MySQL для более эффективной работы:
shell> myisamchk -rq —sort-index —analyze имя_та блицы. MYI
Похожая процедура предусмотрена и для таблиц ISAM. После использования
packJLsam перестройте индексы с помощью isamchk:
shell> isamchk -rq —sort-index —analyze имя_таблицы. ISM
После установки упакованной таблицы в каталог данных MySQL потребуется вы-
полнить mysqladmin flush-tables, чтобы заставить mysqld начать работать с этой таб-
лицей.
Чтобы распаковать ранее сжатую таблицу, используйте опцию —unpack программы
myisamchk или isamchk.

7.3. Инструмент командной строки mysql


mysql - это простая SQL-оболочка (снабженная средствами GNU readline). Она
поддерживает интерактивный и не интерактивный режимы работы. Когда используется
интерактивно, результаты запросов представляются в формате ASCII-таблицы. При ра-
боте в неинтерактивном режиме (например, в качестве фильтра), результат имеет фор-
мат, разделенный знаком табуляции. Формат вывода может быть изменен с помощью
опций командной строки.
Если у вас возникают проблемы, вызванные недостатком памяти при размещении
больших результирующих наборов, используйте опцию —quick. Это заставит mysql из-
влекать результаты от сервера по одной строке, вместо того, чтобы получить ответ сразу
468 Глава 7. Клиентские программы и утилиты MySQL

весь и буферизировать его перед выводом. Для получения результата необходимо будет
вызывать mysql_use_result () вместо mysql_store_result ().
Использование mysql очень просто. Вызовите его из командной оболочки, как пока-
зано ниже:
s h e l l > mysql имя_базы__данных
или
s h e l l > mysql —\1зег=имя_пользователя —password=napojib имя__базы_данных
Затем вводите операторы SQL, завершая каждый символом ' ; ' , \д или \G и нажимая
клавишу <Enter>.
Вы также можете запускать сценарии следующим образом:
s h e l l > mysql имя_базы__данных < s c r i p t . s q l > output.tab
mysql поддерживает следующие опции:
• — h e l p , - ? . Выводит страницу справки и завершает работу.
• —batch, -В. Печатает результаты, используя символ табуляции в качестве разде-
лителя столбцов; каждая запись таблицы находится в отдельной строке. С этой
опцией mysql не использует файл хронологии.
• — c h a r a c t e r - s e t s - d i r = n y T b . Каталог, в котором установлен символьный набор.
См. раздел 4.7.1.
• —compress, -С. Сжимает всю информацию, пересылаемую между клиентом и
сервером, если оба поддерживают сжатие.
• —databaзе=имя_базы_данных, -D имя_базы_данных. База данных, с которой нужно
работать. Обычно указывается в конфигурационном файле.
• —debug [=опции_отладш], -# [опции_отладки]. Записывает журнал отладки.
Обычно строка опции_отладки имеет формат ' d : t : o , и м я _ ф а й л а \ П о умолчанию
'd:t:o,/tmp/mysql.trace 1 .
• —debug-info, -T. Печатает некоторую отладочную информацию при завершении
работы программы.
• —default-character-set=Ha6op. Использует набор в качестве набора символов
по умолчанию. См. раздел 4.7.1.
• —execute=onepaTop, -e оператор. Выполняет оператор и завершает работу. Фор-
мат по умолчанию такой же, как при использовании — b a t c h .
• — f o r c e , -f. Продолжает работу, даже если возникнет ошибка SQL.
• —host=H/wi_xocTa, -h имя_хоста. Подключается к серверу MySQL на указанном
хосте.
• --html, -H. Генерирует вывод в формате HTML.
• --ignore-space, - i . Игнорирует пробелы после имен функций. Эффект от этой
опции описывается в ходе обсуждения IGNORE_SPACE в разделе 4.2.2.
• — l o c a l - i n f i l e [ = {0 11} ]. Включает и выключает свойство LOCAL для LOAD DATA
INFILE. Если ничего не указано, опция включает LOCAL. Для явного включения и
выключения следует использовать --local-infile=0 или ~ l o c a l - i n f i l e = l .
Включение LOCAL не имеет эффекта, если сервер его не поддерживает.
7.3. Инструмент командной строки mysql 469

• —named-commands, -G. Именованные команды включены. Длинный формат команд


разрешен, равно как и сокращенный, подобный \*. Например, распознается как
quit, так и /q.
• —no-auto-rehash, -А. Автоматическое повторное хеширование не используется.
Эта опция заставляет mysql стартовать быстрее, но вы должны будете выдавать
команду rehash, если хотите использовать завершение имен таблиц и столбцов.
• —no-beep, -b. He выдает звуковой сигнал при возникновении ошибки.
• —no-named-commands, -g. Именованные команды отключены. Используется толь-
ко форма \* либо именованные команды должны указываться только в начале
строки, завершающейся точкой с запятой (;). Начиная с MySQL 3.23.22, mysql за-
пускается с этой опцией, включенной по умолчанию. Однако даже в этом случае
длинноформатные команды по-прежнему работают с первой строки.
• —no-pager. He использует программу разбиения на страницы для просмотра от-
вета на запрос. Разбиение вывода на страницы обсуждается далее, в разделе 7.3.1.
• —no-tee. He копировать вывод в файл. Файлы вывода обсуждаются в разделе
7.3.1.
• —one-database, -0. Игнорирует все операторы кроме тех, что имеют отношение к ба-
зе данных по умолчанию, указанной в командной строке. Это удобно для того, что-
бы пропускать изменения в других базах, зафиксированные в бинарном журнале.
• --pager[^команда]. Использует указанную команду для постраничного просмот-
ра ответа на запрос. Если команда не указана, ее имя берется из переменной ок-
ружения PAGER. Допустимыми программами разбиения на страницы могут быть
less, more, cat [> filename] и так далее. Эта опция работает только в Unix. Она
не работает в пакетном режиме. Файлы вывода обсуждаются в разделе 7.3.1.
• — pas sword [^пароль], -р [пароль]. При подключении к серверу использовать ука-
занный пароль. Имейте в виду, что если вы пользуетесь краткой формой этой оп-
ции (-р), то не должны оставлять пробел между флажком опции и паролем. Если
в командной строке пароль не указан, он будет запрошен интерактивно.
• —ро г Ь=номер_порта, -Р номер_ пор та. Номер порта TCP/IP для подключения.
• —prompt^ строка_формата. Устанавливает формат приглашения. По умолчанию
используется mysql>. Специальные символьные последовательности, которые
можно использовать, описаны в разделе 7.3.1.
• — protocol={TCP I SOCKET | PIPE | MEMORY}. Сетевой протокол для подключе-
ния к серверу. Эта опция появилась в MySQL 4.1.
• --quick, -q. He кэширует каждый результат запроса, печатает каждую строку по
мере получения. Это может вызвать задержки в работе сервера, если вывод при-
останавливать. С этой опцией mysql не использует файл хронологии.
• —raw, -r. Выводит значения столбцов без преобразования управляющих симво-
лов. Обычно используется с опцией —batch.
• —reconnect. Если связь с сервером разорвана, автоматически пытается ее восста-
новить. Одна попытка восстановления подключения предпринимается каждый раз
после потери связи. Чтобы подавить эти попытки, нужно использовать опцию
—skip-reconnect. Введено в MySQL 4.1.0.
470 Глава 7. Клиентские программы и утилиты MySQL

• —safe-updates, — i-am-a-dummy, -U. Разрешает только такие операторы UPDATE и


DELETE, в которых указаны строки, подвергаемые изменению с использованием
значений ключей. Если эта опция указана в конфигурационном файле, ее можно
перекрыть, задав —safe-updates в командной строке. Более подробная информа-
ция об этой опции представлена в разделе 7.3.3.
• —silent, -s. Режим минимального количества сообщений. Генерирует минимум
выходной информации. Эту опцию можно указать несколько раз, чтобы еще
больше ограничить объем вывода.
• —skip-column-names, -N. Не выводить имена столбцов в результате.
• —skip-line-numbers, -L. Не указывать номера строк для ошибок. Применимо в
случаях, когда вы хотите сравнить результирующие файлы, в которых включены
сообщения об ошибках.
• —socket=nyTb, -S путь. Файл сокета, используемый для подключения.
• —table, - t . Выводит результат в табличном формате. Этот формат используется
по умолчанию при интерактивном режиме, но может быть применен и в пакетном
режиме.
• —tee=HM#_файла. Добавляет копию выходного потока в указанный файл. Эта оп-
ция не работает в пакетном режиме. Файлы вывода обсуждаются в разделе 7.3.1.
• --unbuffered, -n. Сбрасывает содержимое буфера после каждого запроса.
• —изег=имя_пользователя, -и имя_пользователя. Указывает имя пользователя
MySQL для подключения к серверу.
• --verbose, -v. Режим расширенных сообщений. Генерирует более подробный вы-
вод. Эту опцию можно указать несколько раз, что приводит к большему и боль-
шему объему вывода. (Например, -v -v -v приводит к табличному формату вы-
вода даже в пакетном режиме).
• —version, -V. Выводит информацию о версии и завершает работу.
• —vertical, -E. Печатает строки вывода вертикально. Без этой опции вы можете
указать необходимость вертикального вывода для отдельных операторов, завер-
шая их символами \G.
• —wait, -w. Если соединение не может быть установлено, ожидать и повторять по-
пытки, а не прерывать работу.
• —xml, -X. Генерировать вывод в формате XML.
Можно также установить значения следующих переменных, используя опцию
—имя__ переменной^ зна чение:
• connect_timeout. Таймаут подключения в секундах (по умолчанию 0).
• maxallowedpacket. Максимальная длина пакета для отправки или приема с сер-
вера (по умолчанию 16 Мбайт).
• m a x j o i n s i z e . Автоматический предел на количество строк в соединении при
использовании —safe-updates (по умолчанию 1 000 000).
• n e t b u f f e r l e n g t h . Размер буфера для подключений через TCP/IP и сокеты (по
умолчанию 16 Кбайт).
7.3. Инструмент командной строки mysql 471

• s e l e c t l i m i t . Автоматический предел для оператора SELECT при использовании


—safe-updates (go умолчанию 1 000).
Существует возможность устанавливать переменные, используя синтаксис
--set-уаг1аЫе=имя_леременяой5= значение или -0 имя_переменной= значение. Однако,
начиная с версии MySQL 4.0, этот синтаксис считается устаревшим.
В Unix клиентская программа mysql записывает исполняемые операторы в файл хро-
нологии. По умолчанию он называется .mysql J i i s t o r y и находится в домашнем катало-
ге пользователя. Чтобы указать другой файл, установите значение переменной окруже-
ния MYSQL_HISTFILE.
Если вы не хотите поддерживать файл хронологии, сначала удалите файл
,mysql_history, если он существует, и затем воспользуйтесь любой из следующих про-
цедур:
• Установите значение переменной MYSQLJilSTFILE равным /dev/null. Чтобы эта
установка выполнялась автоматически при каждом входе в систему, внесите соот-
ветствующую строку в один из ваших сценариев запуска.
• Создайте символическую ссылку ,mysql_history, указывающую на /dev/null:
shell> In -s /dev/null $HOME/.mysql_history
Это нужно сделать только однажды.

7.3.1. Команды mysql


mysql посылает вводимые вами SQL-операторы для выполнения на сервер. Но суще-
ствует также набор команд, которые mysql интерпретирует самостоятельно. Чтобы по-
лучить список этих команд, введите help или \h в приглашении командной строки
mysql:
mysql> help
MySQL commands:
(\h) Synonym for 4help'.
clear (\c) Clear command.
connect (\r) Reconnect to the server.
Optional arguments are db and host.
delimiter (\d) Set query delimiter.
edit (\e) Edit command with $EDITOR.
ego (\G) Send command to mysql server,
display result vertically.
exit (\q) Exit mysql. Same as quit.
go (\g) Send command to mysql server.
help (\h) Display this help.
nopager (\n) Disable pager, print to stdout.
notee (\t) Don't write into outfile.
pager (\P) Set PAGER [to__pager] .
Print the query results via PAGER.
print (\p) Print current command.
prompt (\R) Change your mysql prompt.
quit (\q) Quit mysql.
rehash (\#) Rebuild completion hash.
source (\.) Execute an SQL script file.
472 Глава 7. Клиентские программы и утилиты MySQL

Takes a f i l e name as an argument.


status (\s) Get status information from the server.
system (\!) Execute a system shell command.
tee (\T) Set outfile [to__outfile] .
Append everything into given outfile.
use (\u) Use another database.
Takes database name as argument.
Команды MySQL:
•p (\h) Синоним для ' h e l p ' .
clear (\c) Команда очистки.
connect (\r) Повторно подключиться к серверу.
Необязательными аргументами являются db и host.
delimiter (\d) Установить разделитель запросов.
edit (\e) Редактировать с помощью $EDITOR.
ego (\G) Послать команду серверу mysql,
отобразить результат вертикально.
exit (\q) Завершить mysql. To же, что и quit.
go (\g). Послать команду серверу mysql.
help (\h) Вывести эту справку.
nopager (\n) Отключить разбиение на страницы, выводить в stdout.
notee (\t) Не записывать вывод в файл.
pager (\P) Установить PAGER [to_pager].
Печатать результаты запроса через PAGER.
print (\p) •Печатать текущую команду.
prompt (\R) Изменить формат приглашения mysql.
quit (\q) Завершить mysql.
rehash (\#) Перестроить хеш завершения.
source (\.) Выполнить файл сценария SQL.
Принимает в качестве аргумента имя файла.
status (\s) Получить информацию о состоянии из сервера.
system (\!) Выполнить команду системной оболочки.
tee (\T) Установить файл вывода [to_outfile].
Дописывать все в конец заданного файла вывода.
use (\u) Использовать другую базу данных.
Принимает в качестве аргумента имя базы данных.
Команды edit, nopager, pager и system работают только под Unix.
Команда status выводит некоторую информацию о подключении и сервере, который
вы используете. Если вы работаете в режиме —safe-updates, status также печатает
значения переменных mysql, которые затрагивают ваши запросы.
Чтобы регистрировать запросы и их результаты, используйте команду tee. Вся ин-
формация, выводимая на экран, будет дублироваться в заданном файле. Это может
весьма пригодиться во время отладки. Вы можете включать это средство в командной
строке с помощью опции —tee или интерактивно, вводя команду tee. Отключить дей-
ствие команды можно командой notee. Повторный ввод tee возобновляет регистрацию
в журнале. Если ввести tee без параметра, будет использоваться предыдущий файл.
Имейте в виду, что tee сбрасывает результаты запроса в файл после каждого оператора,
перед тем как mysql выведет очередное приглашение на ввод.
Просмотр и поиск в результатах запроса в интерактивном режиме с помощью внеш-
них программ Unix, подобных less, more, теперь возможен с опцией —pager. Если не
7.3. Инструмент командной строки mysql 473

указывать никакого значения этой опции, mysql проверяет значение переменной окру-
жения PAGER и использует его в качестве имени программы просмотра. Постраничный
просмотр вывода можно включать интерактивно командой pager и отключать командой
nopager. Эта команда принимает необязательный аргумент. Если он есть, устанавлива-
ется указанная им программа просмотра. Если аргумента нет, выбирается программа,
переданная в опции командной строки, а если не указана и там, то для просмотра ре-
зультатов запросов используется стандартный вывод stdout.
Постраничный просмотр работает только в средах Unix, так как для него применяет-
ся функция рореп (), которая в Windows отсутствует. Для Windows вместо этого можно
использовать команду tee, которая сохранит весь вывод запроса в файле, несмотря на то
что в ряде случаев для просмотра результатов это не так удобно, как применение pager.
Вот несколько советов относительно команды pager:
• Вы можете использовать эту команду для вывода в файл, при этом результаты по-
ступят только в файл:
mysql> pager cat > /tmp/log.txt
Вы можете также передавать любые опции программе, используемой для постра-
ничного просмотра:
mysql> pager less -n -i -S
• В предыдущем примере обратите внимание на опцию -S. Это удобно для про-
смотра очень широких результатов запроса. Иногда такие результирующие набо-
ры очень трудно читать на экране. Опция -S программы less может помочь в по-
добной ситуации, поскольку позволит выполнять горизонтальную прокрутку ши-
рокого текста с помощью клавиш со стрелками вправо и влево. Вы можете
использовать -S интерактивно внутри less, чтобы включать и отключать режим
горизонтальной прокрутки. Более подробную информацию можно получить из
руководства по less:
shell> man less
• Есть возможность задавать очень сложные команды постраничного просмотра
для работы с результатами запросов:
mysql> pager cat | tee /drl/tmp/res.txt \
| tee /dr2/tmp/res2.txt | less -n -i -S
В этом примере команда будет отправлять результат запроса в два файла, которые
хранятся в двух разных каталогах на двух разных файловых системах, смонтиро-
ванных на /drl и /dr2, вдобавок отображая его на экране командой less.
Вы можете комбинировать функции tee и pager. Имея включенным tee и pager, ус-
тановленным в less, вы сможете просматривать результат в less и одновременно со-
хранять вывод в файле. Разница между Unix-командой tee, применяемой с командой
pager, и встроенной в mysql командой tee состоит в том, что встроенная команда tee
работает, даже если соответствующая команда Unix недоступна. Встроенная команда
tee регистрирует в журнале все, что выводится на экран, в то время как Unix-команда
tee, применяемая совместно с pager, записывает не все.
Кроме того, регистрацию в журнале встроенной командой tee можно включать и от-
ключать интерактивно внутри mysql. Это удобно, если вы хотите регистрировать только
некоторые запросы, но не все.
474 Глава 7. Клиентские программы и утилиты MySQL

Начиная с MySQL 4.0.2, приглашение по умолчанию mysql> можно изменить. Стро-


ка, определяющая приглашение, может включать следующие специальные последова-
тельности:
Опция Описание
\v Версия сервера.
\d Текущая база данных.
\h Хост сервера.
\р Текущий хост TCP/IP.
\и Ваше имя пользователя.
\U Полное имя учетной записи пользователя u s e r_n ame @ h о s t _ n ame.
\\ Литеральный символ'V.
\п Символ перевода строки.
\t Символ табуляции.
\ Пробел (следует за обратной косой чертой).
\_ Пробел.
\R Текущее время в 24-часовом формате.
\г Текущее время в стандартном 12-часовом формате.
\т Минуты текущего времени.
\у Текущий год, двузначное число.
\Y Текущий год, четырехзначное число.
\D Полная текущая дата.
\s Секунды текущего времени.
\w Текущий день недели в трехсимвольном формате (Моп, Tue,...).
\Р am/pm.
\о Текущий месяц в числовом формате.
\0 Текущий месяц в трехсимвольном формате (Jan, Feb,...).
\с Счетчик, увеличивающийся с каждым введенным оператором.

Символ ' \ ' с последующей любой буквой просто представляет эту букву.
Если вы вводите команду prompt без аргументов, mysql возвращает приглашение к
значению по умолчанию - mysql>.
Приглашение можно установить разными способами:
• Используя переменную окружения. Вы можете в переменной окружения уста-
новить строку приглашения mysql, например:
shell> export MYSQLJ>S1=" (\u@\h) [\d]> "
• Используя конфигурационный файл. Вы можете установить форму приглаше-
ния в группе [mysql] конфигурационного файла MySQL - /etc/my.cnf или
.my. cnf в домашнем каталоге. Например:
[mysql]
prompt=(\\u@\\h) [\\d]>\\_
7.3. Инструмент командной строки mysql 475

Обратите внимание, что в этом примере обратные косые черты дублируются. Ес-
ли вы установите приглашение, используя опцию prompt в конфигурационном
файле, желательно дублировать обратные косые черты, когда используются спе-
циальные параметры приглашения. Набор допустимых параметров приглашения
частично переопределяется со специальными управляющими последовательно-
стями, которые распознаются в конфигурационных файлах. (Эти последователь-
ности перечислены в разделе 3.3.2.) Это переопределение может привести к про-
блемам, если использовать одинарные обратные косые черты. Например, \s будет
интерпретироваться как пробел вместо того, чтобы означать секунды текущего
времени. В следующем примере показано, как определить приглашение в конфи-
гурационном файле, чтобы включить в него текущее время в формате ЧЧ:ММ:СС>:
[mysql]
prompt="\\r:\\m:\\s> "
• Используя опцию командной строки. Можно установить приглашение в опции
—prompt командной строки mysql, например:
shell> mysql --prompt=" (\u@\h) [\d]> "
{пользователь®хост) [база__данных] >
• Интерактивно. Изменить форму приглашения можно также интерактивно, ис-
пользуя команду prompt (или \R), например:
mysql> prompt (\u@\h) [\d]>\_
PROMPT set to '(\u@\h) [\d]>\_'
{пользователь®хост) [база^данных]>
{пользователь®хост) [база_данных]> prompt
Returning to default PROMPT of mysql>
mysql>

7.3.2. Запуск SQL-операторов из текстового файла


Клиентская программа mysql обычно используется интерактивно:
shell> mysql имя_базы_данных
Однако существует возможность поместить SQL-операторы в файл с тем, чтобы
mysql прочитал их оттуда и выполнил. Чтобы сделать это, создайте текстовый файл тек-
стовый_файл, содержащий требуемые операторы. Затем запустите mysql, как показано
ниже:
shell> mysql имя_базы_данных < текстовый_файл
Вы можете также поместить в начало файла оператор USE имя_базы_данных. В этом
случае нет необходимости указывать базу данных в командной строке:
shell> mysql < текстовый^файл
Если mysql уже запущен, вы можете выполнить файл SQL-сценария, используя либо
команду source, либо \.:
mysql> source имя_файла;
mysql> \. имя_файла
476 Глава 7. Клиентские программы и утилиты MySQL

7.3.3. Советы по mysql


В этом разделе описаны некоторые приемы, позволяющие использовать mysql более
эффективно.

7.3.3.1. Вертикальный вывод результатов запроса


Некоторые результаты запросов гораздо лучше воспринимаются, если их выводить
вертикально, вместо обычного горизонтального табличного формата. Например, длин-
ные текстовые значения, которые включают в себя переводы строк, часто гораздо легче
читать в вертикальном формате:
m y s q l > SELECT * FROM m a i l s WHERE LENGTH(txt) < 300 LIMIT 300,1\G
*************************** i# r o w ***************************
msg_nro: 3068
date: 2000-03-01 23:29:50
time_zone: +0200
mail_from: Monty
reply: [email protected]
mail_to: "Thimble Smith" <[email protected]>
sbj: UTF-8
txt: > » » "Thimble" == Thimble Smith writes:
Thimble> Hi. I think this is a good idea. Is anyone familiar
Thimble> with UTF-8 or Unicode? Otherwise, I'll put this on my
Thimble> TODO list and see what happens.
Yes, please do that.
Regards,
Monty
file: inbox-jani-1
hash: 190402944
1 row in set (0.09 sec)

7.3.3.2. Применение опции - -safe-updates


Опция --safe-updates (или —i-am-a-dummy) удобна для начинающих пользователей.
Эта опция была введена в MySQL 3.23.11. Она полезна в случаях, когда вы непреднаме-
ренно вводите оператор DELETE FROM имя__таблицы без конструкции WHERE. Обычно такой
оператор удаляет все строки в таблице. С опцией --safe-updates строки будут удалены
только в случае указания ключевых значений, которые их идентифицируют. Это позво-
ляет предотвратить крупные неприятности.
Когда вы используете опцию --safe-updates, mysql при подключении отправляет на
сервер следующий оператор:
SET SQL_SAFE_UPDATES=l,SQL_SELECT_LIMIT=1000, SQL_MAX_JOIN_SIZE=1000000;

Этот оператор SET приводит к следующим эффектам:


• Вы не имеете возможности выполнять операторы UPDATE и DELETE, если только не
укажете ключевое условие в конструкции WHERE либо не добавите конструкцию
LIMIT (либо то и другое). Например:
UPDATE имя_таблицы SET not_key_column=# WHERE key_column=#;
UPDATE имя_таблицы SET not_key_column=# LIMIT 1;
7.4. Программа администрирования MySQL-сервера mysqladmin 477

• Все большие результаты запросов SELECT ограничиваются 1000 строк, если только
не включают конструкцию LIMIT.
• Многотабличные операторы SELECT, которые предположительно должны прове-
рить более 1 000 000 комбинаций строк, прерываются.
Чтобы указать ограничения, отличные от 1000 и 1000000, вы можете переопределить
умолчания, используя опции —select_limit и —max_join_size:
shell> mysql --safe-updates --select_limit=500 --max_join_size=10000

7.3.3.3. Отключение автоматического восстановления соединений mysql


Если программа mysql теряет соединение с сервером в процессе выполнения запроса,
она немедленно автоматически пытается восстановить это соединение и отправить за-
прос снова. Однако даже если mysql удастся это сделать, ваше первое соединение пре-
рвется, и все ваши предыдущие установки и объекты сеанса будут потеряны: временные
таблицы, режим автоматической фиксации транзакций, пользовательские и системные
переменные. Такое поведение может оказаться довольно-таки опасным, как в следую-
щем примере, где сервер был остановлен и перезапущен без вашего ведома:
mysql> SET @a=l;
Query OK, 0 rows affected (0.05 sec)
mysql> INSERT INTO t VALUES(@a);
ERROR 2006: MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 1
Current database: test
Query OK, 1 row affected (1.30 sec)
mysql> SELECT * FROM t;

I a |
+ +
| NULL |

1 row in set (0.05 sec)


Пользовательская переменная @а была утеряна вместе с соединением, а после его
восстановления стала неопределенной. Если важно, чтобы клиентская программа mysql
была прервана с сообщением об ошибке при утере соединения, вы можете запустить ее с
опцией —skip-reconnection.

7.4. Программа администрирования


MySQL-сервера mysqladmin
mysqladmin - это клиентская программа, предназначенная для выполнения операций
администрирования. Вы можете использовать ее для проверки конфигурации и текущего
состояния сервера, создания и удаления баз данных, и многого другого.
Запуск выглядит mysqladmin так:
s h e l l > mysqladmin [опции] команда [опции-команды] команда ...
mysqladmin поддерживает следующие команды:
478 Глава 7. Клиентские программы и утилиты MySQL

• create имя__базы_данных. Создать новую базу данных.


• drop имя_базы_данных. Удалить базу данных и все ее таблицы.
• extended-status. Вывести переменные состояния сервера и их значения.
• flush-hosts. Сбросить всю информацию из кэша хостов.
• flush-logs. Сбросить все журналы.
• flush-privileges. Перезагрузить таблицы привилегий (то же, что и reload).
• flush-status. Очистить переменные состояния.
• flush-tables. Сбросить буферы таблиц.
• flush-threads. Сбросить кэш потоков (добавлена в MySQL 3.23.16).
• k i l l идентификатор, идентификатор,.... Прервать потоки сервера.
• password новый-пароль. Назначить новый пароль. Это изменяет пароль на новый-
пароль для учетной записи, под которой вы подключились к серверу программой
mysqladmin.
• ping. Проверить, работает ли сервер.
• processlist. Вывести список активных серверных потоков. Это то же самое, что
и вывод оператора SHOW PROCESSLIST. Если указана опция —verbose, вывод будет
подобен выводу оператора SHOW FULL PROCESSLIST.
• reload. Перезагрузить таблицы привилегий (то же, что и flush-privileges).
• refresh. Сбросить буферы всех таблиц, закрыть и открыть файлы журналов.
• shutdown. Остановить сервер.
• s t a r t - s l a v e . Запустить репликацию на подчиненном сервере (добавлена в
MySQL 3.23.16).
• status. Вывести краткое сообщение о состоянии сервера.
• stop-slave. Остановить репликацию на подчиненном сервере (добавлена в
MySQL 3.23.16).
• variables. Вывести системные переменные сервера и их значения.
• version. Показать номер версии сервера.
Все команды могут быть сокращены до любого уникального префикса. Например:
shell> mysqladmin proc stat
+ + + + + + + + +
I Id | User | Host | db | Command | Time | State I Info |

I 6 | monty | localhost I I Processlist | 0 | I |


+ + + + + + + + +
Uptime: 10077 Threads: 1 Questions: 9 Slow queries: 0
Opens: 6 Flush tables: 1 Open tables: 2
Memory in use: 1092K Max memory used: 1116K
Команда status в mysqladmin выводит следующие значения:
• Uptime. Длительность работы сервера в секундах.
• Threads. Количество активных потоков (клиентов).
7.4. Программа администрирования MySQL-сервера mysqladmin 479

• Questions. Количество клиентских запросов с момента старта сервера.


• Slow queries. Количество запросов, на выполнение которых потребовалось более
long_query_time секунд.
• Opens. Количество таблиц, открытых сервером.
• Flush tables. Количество выполненных сервером команд flush . . . , refresh и
reload.
• Open tables. Количество таблиц, открытых в данный момент.
• Memory in use. Общий объем памяти, распределенный непосредственно кодом
mysqld. Это значение отображается, только если MySQL был скомпилирован с
опцией --with-debug-full.
• Maximum memory used. Максимальный объем памяти, распределенный непосред-
ственно кодом mysqld. Это значение отображается, только если MySQL был
скомпилирован с опцией —with-debug-full.
Если вы выполняете mysqladmin shutdown, подключившись к локальному серверу с
использованием файла сокета Unix, mysqladmin ожидает, пока файл идентификатора про-
цесса сервера будет удален, чтобы гарантировать, что сервер был остановлен правильно.
mysqladmin поддерживает следующие опции:
• —help, -?. Выводит страницу справки и завершает работу.
• —character-sets-dir=nyTb. Каталог, в котором установлен символьный набор.
См. раздел 4.7.1.
• —compress, -С. Сживает всю информацию, передаваемую между клиентом и сер-
вером, если оба они поддерживают сжатие.
• —count=#, -с #. Количество итераций, которые необходимо выполнить. Работает
только с опцией —sleep (-i).
• — debug[=опции__отладки], -# [опции^отладки]. Записывает журнал отладки.
Обычно строка опции_отладки представляется в формате 'd:t:o,имя_файла*. По
умолчанию 'd:t:о,/tmp/mysqladmin.trace'.
• —force, -f. He запрашивает подтверждения команды drop database. В случае
набора команд продолжает работу даже при возникновении ошибок.
• —host=HM#_xocTa, -h опции__отладки. Подключается к серверу MySQL на указан-
ном хосте.
• —password[=лароль], -р[пароль]. При подключении к серверу использует ука-
занный пароль. Имейте в виду, что если вы применяете краткую форму этой оп-
ции (-р), то не должны оставлять пробел между названием опции и паролем. Если
в командной строке пароль не указан, он будет запрошен интерактивно.
• — рог t=HOMep_nopTaf -Р номерпорта. Номер порта TCP/IP для подключения.
• —protocol={TCP I SOCKET I PIPE | MEMORY}. Сетевой протокол для подключе-
ния к серверу. Эта опция была введена в MySQL 4.1.
• — r e l a t i v e , -г. Показывает разницу между текущим и предыдущим значением,
когда применяется вместе с -i. В настоящее время эта опция работает только с
командой extended-status.
480 Глава 7. Клиентские программы и утилиты MySQL

• —silent, -s. Завершает работу молча, если невозможно установить подключение


к серверу.
• —si 1р=задержка, - i задержка. Повторяет выполнение команды с задержкой
задержка между попытками.
• — socket=nyTb, -S путь. Файл сокета, используемый для подключения.
• —изег=имя_пользователя, -и имя_пользователя. Указывает имя пользователя
MySQL для подключения к серверу.
• —verbose, -v. Режим расширенных сообщений. Генерирует более подробный вывод.
• —version, -V. Выводит информацию о версии и завершает работу.
• —vertical, -E. Печатает строки вывода вертикально. Похоже на —relative, но
печатает вывод вертикально.
• —wait [=#], -w [#]. Если соединение не может быть установлено, ожидает и по-
вторяет попытки вместо того, чтобы прерывать работу. Если значение опции ука-
зано, оно задает количество повторных попыток (по умолчанию 1).
Можно также установить следующие переменные с помощью опции —имя_переменной=
значение:
• connect __timeout. Количество секунд таймаута подключения (по умолчанию 0).
• shutdown_timeout. Задержка при останове сервера в секундах (по умолчанию 0).
Вы можете также установить значения переменных, используя синтаксис —set-variable=
имя_переменной= значение или -0 имя_переменной=значение. Однако, начиная с версии
MySQL 4.0, этот синтаксис считается устаревшим.

7.5. Утилита работы с бинарными журналами


mysqlbinlog
Файлы бинарных журналов, которые генерирует сервер, записываются в двоичном
формате. Для просмотра их содержимого в текстовом виде служит утилита mysqlbinlog.
Она доступна, начиная с версии MySQL 3.23.14.
Вызов mysqlbinlog выглядит следующим образом:
shell> mysqlbinlog [опции] файл-журнала . . .
Например, чтобы отобразить содержимое бинарного журнала binlog.000003,
воспользуйтесь командой:
shell> mysqlbinlog binlog.0000003
Вывод этой команды включает все операторы, содержащиеся в binlog.000003, вме-
сте с дополнительной информацией, такой как время выполнения каждого оператора,
идентификатор потока клиента, который его вызвал, временная метка и так далее.
Обычно mysqlbinlog используется для непосредственного чтения файлов бинарных
журналов и применения на локальном сервере MySQL. Существует также возможность
читать бинарные журналы с удаленного сервера, если использовать опцию —read-f rom-
remote-server. Однако эта практика считается устаревшей, поскольку вместо этого
мы, прежде всего, стараемся упростить работу с бинарными журналами на локальном
сервере.
7.5. Утилита работы с бинарными журналами mysqlbinlog 481

Когда бинарный журнал читается с удаленного сервера, опции параметров соедине-


ния могут указывать, как подключаться к серверу, но они игнорируются, если не указана
опция —read-from-remote-server. Опции параметров подключения таковы: —host,
—password, —port, —protocol, —socket и —user.
mysqlbinlog можно также использовать для чтения журналов, которые пишет подчи-
ненный сервер при репликации. Журналы ретрансляции имеют тот же формат, что и
обычные бинарные журналы.
Бинарные журналы подробно описываются в разделе 4.8.4.
mysqlbinlog поддерживает следующие опции:
• —help, -?. Выводит страницу справки и завершает работу.
• —databaэе=:имя_базы_данных, -d имя_базы_данных. Выводит информацию, ка-
сающуюся указанной базы данных (только для локальных журналов).
• —force-read, -f. Принудительное чтение неизвестных событий в бинарном жур-
нале.
• —host=HM#_xocTa, -h имя_хоста. Читает бинарный журнал с сервера MySQL на
указанном хосте.
• — local-load=nyTb, -1 путь. Подготавливает локальные временные файлы в ука-
занном каталоге для LOAD DATA INFILE.
• —of f set=N, -o N. Пропускает первые N позиций.
• —pas sword [=пароль], -р[пароль]. При подключении к серверу использует ука-
занный пароль. Имейте в виду, что если вы применяете краткую форму этой оп-
ции (-р), то не должны оставлять пробел между названием опции и паролем. Если
в командной строке пароль не указан, он будет запрошен интерактивно.
• —port=HOMep_nopTa, -P номер_порта. Номер порта TCP/IP для подключения.
• —position=N, - j N. Начинает читать бинарный журнал с позиции N.
• —protocol={TCP I SOCKET | PIPE I MEMORY}. Сетевой протокол для подключе-
ния к серверу. Эта опция появилась в MySQL 4.1.
• —read-from-remote-server, -R. Читает бинарный журнал с сервера MySQL. Лю-
бые параметры подключения игнорируются, если не указана эта опция. Парамет-
ры подключения задаются опциями —host, —password, —port, —protocol,
—socket и —user.
• — r e s u l t - f Пе-пате=имя, -г имя. Направляет вывод в указанный файл.
• —short-form, -s. Выводит только операторы, содержащиеся в журнале, без до-
полнительной информации.
• --socket=nyTb, -S путь. Файл сокета, используемый для подключения.
• —иБег-имя_пользователя9 -и имя_пользователя. Указывает имя пользователя
MySQL для подключения к серверу.
• —version, -V. Выводит информацию о версии и завершает работу.
Можно также установить следующие переменные с помощью опции —имя_переменной=
значение:
• open_files_limit. Указывает количество открытых файловых дескрипторов для
резервирования.
482 Глава 7. Клиентские программы и утилиты MySQL

Можно перенаправить вывод программы mysqlbinlog на вход клиента mysql, чтобы


выполнить операторы, содержащиеся в бинарном журнале. Это используется при вос-
становлении после аварий, если доступна старая резервная копия (см. раздел 4.6.1):
shell> mysqlbinlog имя^хоста-Ып. 000001 | mysql
или
shell> mysqlbinlog имя_хоста-Ып. [0-9]* | mysql
Вместо этого можно перенаправить вывод mysqlbinlog в текстовый файл, если необ-
ходимо перед выполнением модифицировать некоторые операторы (например, удалить
некоторые операторы, которые вы не хотите исполнять по каким-то причинам).
После редактирования файла можно выполнить содержащиеся в нем операторы, ис-
пользуя его в качестве входа для mysql.
У mysqlbinlog есть опция --position, которая заставляет его печатать только те опе-
раторы, смещение которых от начала бинарного журнала больше или равно указанному
значению.
Если у вас есть более одного бинарного журнала, которые нужно выполнить на сер-
вере MySQL, безопасный метод сделать это заключается в том, чтобы обработать их,
используя единственное подключение к серверу. Приведем пример, демонстрирующий,
что может оказаться небезопасным:
shell> mysqlbinlog имя_хоста-Ып.000001 | mysql # ОПАСНО!!
shell> mysqlbinlog имя_хоста-Ып.000002 | mysql # ОПАСНО!!
Обработка бинарных журналов, использующих разные подключения к серверу, мо-
жет вызвать проблемы, если первый из них содержит оператор CREATE TEMPORARY TABLE,
а второй - оператор, который обращается к этой временной таблице. Когда выполнение
первого процесса mysql завершится, сервер удалит временную таблицу. И когда второй
процесс попытается обратиться к этой таблице, сервер сообщит об ошибке типа "неиз-
вестная таблица".
Чтобы избежать проблем подобного рода, используйте одно подключение для обра-
ботки содержимого всех необходимых бинарных журналов. Вот один из способов сде-
лать это:
shell> mysqlbinlog имя__хоста-Ып. 000001 имя^хоста-Ып. 000002 | mysql
А вот другой подход:
shell> mysqlbinlog имя_хоста-bin.000001 > /tmp/statements.sql
shell> mysqlbinlog имя_хоста-Ып.000002 » /tmp/statements.sql
shell> mysql -e "source /tmp/statements.sql"
В MySQL 3.23 бинарный журнал не содержал данных для загрузки с помощью опе-
ратора LOAD DATA INFILE. Для выполнения этого оператора из файла бинарного журнала
требовался исходный файл данных. Начиная с MySQL 4.0.14, бинарный журнал содер-
жит эти данные, поэтому mysqlbinlog может генерировать вывод, который воспроизво-
дит операцию LOAD DATA INFILE, без необходимости в исходном файле данных.
mysqlbinlog копирует данные во временный файл и выдает оператор LOAD DATA INFILE,
который ссылается на этот файл. Каталог по умолчанию, куда помещается этот файл,
зависит от системы. Чтобы явно указать каталог, используйте опцию —local-load.
7.6. Центр управления MySQL — mysqlcc 483

Поскольку mysqlbinlog преобразует операторы LOAD DATA INFILE В LOAD DATA LOCAL
INFILE (то есть, добавляет LOCAL), и клиент, и сервер, которые используются для обра-
ботки этих операторов, должны быть настроены так, чтобы разрешать LOCAL.
| Внимание!
Щ Временные файлы, которые создаются для LOAD DATA INFILE, не удаляются автоматически,
Щ поскольку они нужны д о т е х пор, пока в действительности не будут выполнены эти операторы.
Ш Вы должны удалить их самостоятельно после того, как отпадет необходимость в журнале. Э т и
§и файлы можно найти в каталоге временных файлов под именами вроде оригиналь-
Щ ное_имя__ фа ила - # - #.

В будущем мы решим эту проблему, позволив mysqlbinlog подключаться непосред-


ственно к серверу mysqld. Тогда будет можно автоматически безопасно удалять файлы
журналов немедленно после выполнения операторов LOAD DATA INFILE.
До версии MySQL 4.1 утилита mysqlbinlog не могла готовить вывод, подходящий
для mysql, если бинарный журнал содержал смешанные операторы, полученные от раз-
ных клиентов, которые использовали одноименные временные таблицы. В MySQL 4.1
это исправлено.

7.6. Центр управления MySQL — mysqlcc


Центр управления MySQL, mysqlcc, - это не зависящая от платформы клиентская
программа, представляющая графический интерфейс пользователя к серверу базы дан-
ных MySQL. Она поддерживает интерактивную работу, включая выделение цветом син-
таксических конструкций и табуляцию. Обеспечивает управление базами данных и таб-
лицами, а также задачи администрирования сервера.
mysqlcc не входит в состав стандартного дистрибутива MySQL, но может быть за-
гружена отдельно с http://dev.mysql.com/downloads/. В настоящее время mysqlcc ра-
ботает на платформах Windows и Linux.
Запустите mysqlcc, дважды щелкнув на ее пиктограмме в графической среде. Для за-
пуска из командной строки введите следующую команду:
shell> mysqlcc [опции]
mysqlcc поддерживает следующие опции:
• --help, -?. Выводит справочное сообщение и завершает работу.
• —blocking-queries, -b. Использует блокирующие запросы.
• —compress, -С. Сжимает всю информацию, пересылаемую между клиентом и
сервером, если оба поддерживают сжатие.
• —connection-name=HM#, -с имя. Синоним опции —server.
• —databaзе=имя_базы_данных, -d имя_базы_данных. База данных для использова-
ния. В основном применяется в файле конфигурации.
• --history-size=#, -H #. Длина списка хронологии в окне запросов.
• --host=HM#_xocTa, -h имя_базы_данных. Подключается к серверу MySQL на ука-
занном хосте.
• —local-infile[ = {0|l}]. Включает и отключает свойство LOCAL для LOAD DATA
INFILE. Если ничего не указано, опция включает LOCAL. Для явного включения и
484 Глава 7. Клиентские программы и утилиты MySQL

отключения следует использовать —local-infile=0 или —local-infile=l.


Включение LOCAL не имеет эффекта, если сервер не поддерживает его.
• —pass word [-пароль], -р[пароль]. При подключении к серверу использует ука-
занный пароль. Имейте в виду, что если вы указываете краткую форму этой опции
(-р), то не должны оставлять пробел между названием опции и паролем. Если в
командной строке пароль не указан, он будет запрошен интерактивно.
• —plugins_path=MM#, -g имя. Указывает путь к каталогу, в котором содержатся
подключаемые модули центра управления MySQL.
• —port=HOMep_nopTa, -P номер^порта. Номер порта TCP/IP для подключения.
• —query, -q. Открывает при запуске окно запросов.
• —register, -r. Открывает при запуске диалог Register Server (Регистрация
сервера).
• — server=HM*, -s имя. Имя подключения центра управления MySQL.
• —socket=nyTb, -S путь. Файл сокета, используемый для подключения.
• —syntax, -у. Включает выделение цветом синтаксиса и автоматическое завершение.
• —syntax_f Пе=имя, -Y имя. Файл синтаксиса для автоматического завершения.
• —translationj?ath=HM#, -T имя. Указывает путь к каталогу, в котором находятся
файлы переводов центра управления MySQL.
• —изег=имя__пользователя, -и имя_пользователя. Указывает имя пользователя
MySQL для подключения к серверу.
• —version, -V. Выводит информацию о версии и завершает работу.
Можно также установить следующие переменные с помощью опции —имя_переменной=
значение:
• connect_timeout. Таймаут подключения в секундах (по умолчанию 0).
• max_allowed_packet. Максимальная длина пакета для отправки или приема с сер-
вера (по умолчанию 16 Мбайт).
• max_join_size. Автоматический предел на количество строк в объединении при
использовании --safe-updates (по умолчанию 1 000 000).
• net_buffer_length. Размер буфера для подключений через TCP/IP и сокеты (по
умолчанию 16 Кбайт).
• select_limit. Автоматический предел для оператора SELECT при использовании
—safe-updates (по умолчанию 1 000).
Существует возможность устанавливать переменные, используя синтаксис
—set-variable=имя_переменной=значение или -0 имя_переменной=значение. Однако,
начиная с MySQL 4.0, этот синтаксис считается устаревшим.
7.7. Программа обслуживания и восстановления таблиц mysqlcheck 485

7.7. Программа обслуживания и


восстановления таблиц mysqlcheck
Клиентская программа mysqlcheck проверяет и восстанавливает таблицы MylSAM. Она
также может оптимизировать и анализировать таблицы, mysqlcheck доступна, начиная с
MySQL 3.23.38.
mysqlcheck по функциональному назначению похожа на myisamchk, но работает иначе.
Основное отличие состоит в том, что mysqlcheck должна использоваться при запущенном
сервере mysqld, в то время как myisamchk - нет. Выгода от применения mysqlcheck в том,
что для проверки и восстановления таблиц не надо останавливать сервер.
mysqlcheck использует SQL-операторы CHECK TABLE, REPAIR TABLE, ANALYZE TABLE и
OPTIMIZE TABLE удобным для пользователя способом. Она определяет, какой оператор
необходимо применять для выполнения нужной операции, затем отправляет его серверу
на исполнение.
Существуют три основных способа запуска mysqlcheck:
shell> mysqlcheck [опции] имя_6азы_датшх [таблицы]
shell> raysqlcheck [опции] —databases база_данных1 [база__данных2 база_данныхЗ...]
shell> mysqlcheck [опции] —all-databases
Если вы не указываете никаких таблиц или используете опции --databases либо
—all-databases, будут проверены все базы данных.
mysqlcheck имеет некоторые свойства, отличающие ее от других клиентов. Поведе-
ние проверки таблиц по умолчанию (—check) может быть изменено переименованием
самой программы. Если вам нужен инструмент, который будет по умолчанию восста-
навливать таблицы, то вы можете просто скопировать программу mysqlcheck под име-
нем mysqlrepair или создать символическую ссылку с именем mysqlrepair, указываю-
щую на mysqlcheck. Если вы запустите mysqlrepair, она будет по умолчанию восста-
навливать таблицы.
Следующие имена можно использовать для изменения поведения mysqlcheck по
умолчанию:
mysqlrepair По умолчанию используется опция —repair,
mysqlanalyze По умолчанию используется опция —analyze,
mysqloptimize По умолчанию используется опция —optimize.
mysqlcheck поддерживает следующие опции:
• —help, -?. Выводит справочное сообщение и завершает работу.
• —all-databases, -А. Проверяет все таблицы во всех базах данных.
• —all-in-1, - 1 . Вместо того, чтобы выполнять операторы для каждой таблицы,
выполняет отдельный оператор для каждой базы данных, в которой нужно прове-
рить все таблицы.
• —analyze, -а. Анализирует таблицы.
• --auto-repair. Если проверяемая таблица повреждена, автоматически восстанав-
ливает ее. Все необходимые операции по восстановлению выполняются после то-
го, как все таблицы будут проверены.
• —character-sets-dir=nyTb. Каталог, в котором установлен символьный набор.
См. раздел 4.7.1.
486 Глава 7. Клиентские программы и утилиты MySQL

• --check, -с. Проверяет таблицы на предмет ошибок.


• —check-only-changed, -С. Проверяет только те таблицы, которые изменялись с
момента последней проверки или не были корректно закрыты.
• —compress. Сжимает всю информацию, пересылаемую между клиентом и серве-
ром, если оба поддерживают сжатие.
• —databases, -В. Обрабатывает все таблицы в указанных базах данных. С этой оп-
цией все аргументы рассматриваются как имена баз данных, а не таблиц.
• —debug[=опции_отладки], -# [опции_отладки]. Записывает журнал отладки.
Обычно строка опции_отладки имеет формат ' d: t : о, имя_файла'.
• —default-character-set=Ha6op. Использует набор в качестве набора символов
по умолчанию. См. раздел 4.7.1.
• —extended, -e. Если использовать эту опцию при проверке таблиц, это гаранти-
рует, что они будут на 100% исправны и непротиворечивы, но проверка потребует
длительного времени.
Если использовать эту опцию при восстановлении таблиц, будет выполняться
расширенное восстановление, которое не только потребует длительного времени,
но и может сгенерировать огромное количество "мусорных" строк.
• --fast, -F. Проверяет только те таблицы, которые не были корректно закрыты.
• —force, -f. Продолжает работу даже после возникновения ошибок SQL.
• —host=HM*_xocTa, -h имя_хоста. Подключается к серверу MySQL на указанном
хосте.
• —medium-check, -m. Выполнить проверку, которая быстрее, чем при операции
—extended. При этом находятся 99,99% всех ошибок, что может быть достаточно
хорошо в большинстве случаев.
• —optimize, -о. Оптимизировать таблицы.
• --password[^пароль], -р[пароль]. При подключении к серверу использует ука-
занный пароль. Имейте в виду, что если вы указываете краткую форму этой опции
(-р), то не должны оставлять пробел между названием опции и паролем. Если в
командной строке пароль не указан, он будет запрошен интерактивно.
• —port=номер_порта, -Р номер_порта. Номер порта TCP/IP для подключения.
• —protocol={TCP | SOCKET | PIPE | MEMORY}. Сетевой протокол для подключе-
ния к серверу. Эта опция введена в MySQL 4.1.
• —quick, -q. Если использовать эту опцию при проверке таблиц, это предотвраща-
ет сканирование строк для поиска неправильных ссылок. Это наиболее быстрый
способ проверки.
Если использовать эту опцию при восстановлении таблиц, программа пытается вос-
станавливать только индексное дерево. Самый быстрый способ восстановления.
• —repair, -r. Выполняет восстановление, которое может исправить почти все,
кроме уникальных ключей, которые по каким-то причинам оказались неуникаль-
ными.
• —silent, -s. Режим минимального количества сообщений. Выдает в выходной
поток только сообщения об ошибках, если они случаются.
7.8. Программа резервного копирования баз данных mysqldump 487

• —socket=nyTb, -S путь. Файл сокета, используемый для подключения.


• —tables. Перекрывает опцию --databases или -В. Все аргументы трактуются как
имена таблиц.
• —useг=имя_лользователя, -и имя_пользователя. Указывает имя пользователя
MySQL для подключения к серверу.
• —verbose, -v. Режим расширенных сообщений. Выводит информацию о стадиях
функционирования программы.
• --version, -V. Выводит информацию о версии и завершает работу.

7.8. Программа резервного копирования


баз данных mysqldump
Клиентская программа mysqldump может использоваться для выгрузки дампа базы
данных или набора баз данных с целью получения резервной копии или для переноса
данных на другой SQL-сервер (не обязательно MySQL). Дамп содержит SQL-операторы,
необходимые для создания таблиц и/или наполнения их данными.
Если вы создаете резервную копию на сервере, то вам стоит рассмотреть вопрос
применения mysqlhotcopy вместо mysqldump. См. раздел 7.9.
Существует три основных способа запуска mysqldump:
s h e l l > mysqldump [опции] имя_базы_данных [таблицы]
shell> mysqldurap [опции] —databases база_данных1 [база_данных2 база_данныхЗ...]
shell> mysqldurap [опции] —all-databases
Если не указывать имен таблиц либо использовать опцию —databases или — a l l -
databases, будет выгружен полный дамп базы данных.
Чтобы получить полный список опций, которые поддерживает ваша версия
mysqldump, запустите mysqldump —help.
Если вы запускаете mysqldump без опций —quick или —opt, mysqldump полностью за-
гружает в память результирующий набор, прежде чем выгружать его в дамп. Это может
стать причиной проблем, если выгружается большая база данных. Начиная с MySQL 4.1,
опция —opt включена по умолчанию, но может быть отключена с помощью --skip-opt.
Если вы пользуетесь последней копией программы mysqldump и собираетесь генери-
ровать дамп, который должен будет загружаться на очень старый сервер MySQL, указы-
вать опции —opt и -е не следует.
Числовые значения, выходящие за пределы допустимых, такие как inf и -inf, равно
как и NaN (not-a-number), выгружаются программой mysqldump как NULL. Вы можете уви-
деть это, воспользовавшись следующей простой таблицей:
mysql> CREATE TABLE t (f DOUBLE);
mysql> INSERT INTO t VALUES(le+111111111111111111111);
mysql> INSERT INTO t V A L U E S ( - l e l l l l l l l l l l l l l l l l l l l l l ) ;
mysql> SELECT f FROM t ;

inf
-inf
Глава 7. Клиентские программы и утилиты MySQL

Для этой таблицы mysqldump генерирует следующий вывод:

— Дамп данных таблицы Ч %

INSERT INTO t VALUES (NULL);


INSERT INTO t VALUES (NULL);
Такое поведение приводит к тому, что если выгрузить в дамп и затем восстановить
эту таблицу, то содержимое новой таблицы будет отличаться от содержимого ориги-
нальной таблицы.
mysqldump поддерживает следующие опции:
• —help, -?. Выводит справочное сообщение и завершает работу.
• —add-drop-table. Перед каждым оператором CREATE TABLE добавляется DROP
TABLE.
• —add-locks. Окружает дамп каждой таблицы операторами LOCK TABLE и UNLOCK
TABLE. Это ускоряет вставку строк, когда дамп загружается в базу. См. раздел
6.2.12.
• --all-databases, -А. Выгружает все таблицы из всех баз данных. Это то же са-
мое, что применение опции —databases с указанием имен всех баз данных в ко-
мандной строке.
• —all-keywords. Позволяет создавать имена столбцов, совпадающие с ключевыми
словами. Это работает, если каждое такое наименование столбцы сопровождать
префиксом - именем таблицы.
• —comments [ = {011} ]. Если установлено в 0, то дополнительная информация в
дампе подавляется. Это касается номера версии программы, версии сервера, име-
ни хоста. Опция --skip-comments дает тот же эффект, что и --comments=0. Значе-
ние по умолчанию равно 1, что означает не подавлять дополнительную информа-
цию. Опция появилась в MySQL 4.0.17.
• —compatible-name=HM*. Генерирует вывод, который совместим с другими систе-
мами управления базами данных или более старыми версиями сервера MySQL.
Значением аргумента имя может быть mysql323, mysql40, postgresql, oracle,
mssql, db2, sapdb, no_key_options, no_table_options или no_field_options. Что-
бы использовать несколько значений, разделяйте их запятыми. Значение этих оп-
ций имеет тот же смысл, как и соответствующие опции, устанавливающие SQL-
режим сервера. См. раздел 4.2.2.
Эта опция требует сервера версии MySQL 4.1.0 или выше. В более старых версиях
она не делает ничего.
• —complete-insert, -с. Использует полные операторы INSERT, включающие име-
на столбцов.
• —compress, -С. Сжимает всю информацию, пересылаемую между клиентом и
сервером, если оба поддерживают сжатие.
• —create-options. Включает все специфичные для MySQL опции оператора
CREATE TABLE. До версии MySQL 4.1.2 вместо этой опции использовалась —all.
7.8. Программа резервного копирования баз данных mysqldump 489

• --databases, -В. Для выгрузки определенных баз данных. Обратите внимание на


отличия в применении. В этом случае никакие таблицы не указываются. Все ар-
гументы командной строки трактуются как имена баз данных. Оператор USE
имя_базы_данных включается в вывод перед каждой новой базой данных.
• —debug [=опции_отладки], -# [опции_отладки]. Записывает журнал отладки.
Обычно строка опции_отладки имеет формат ' d: t : о, имя_файла'.
• —default-character-set=Ha6op. Использует набор в качестве набора символов
по умолчанию. См. раздел 4.7.1. Если не указан конкретный набор, начиная с
MySQL 4.1.2, используется utf 8; в более старых версиях применялся lati.nl.
• —delayed. Вставляет строки, используя оператор INSERT DELAYED.
• —delete-master-logs. На главном сервере репликации удаляет файлы бинарных
журналов после выполнения операции выгрузки дампа. Опция автоматически
включает — f i r s t - s l a v e . Была добавлена в MySQL 3.23.57 (для MySQL 3.23) и в
MySQL 4.0.13 (для MySQL 4.0).
• —disable-keys, -К. Для каждой таблицы окружить оператор INSERT фрагментами
/ * ! 40000 ALTER TABLE имя^таблицы DISABLE KEYS */ и / * ! 40000 ALTER TABLE
имя_таблицы ENABLE KEYS */. Это ускоряет загрузку данных из дампа на сервер
MySQL, так как в этом случае индексы создаются после загрузки всех данных.
Эффективно только для таблиц My ISAM.
• —extended-insert, -e. Использует многострочный синтаксис INSERT, включаю-
щий несколько списков VALUES. Это уменьшает размер дампа и ускоряет после-
дующую загрузку.
• —fields-terminates-by=...
—fields-enclosed-by=...
—fields-optionally-enclosed-by=...
—fields-escaped-by=...
—fields~terminated-by=...
Эта опция применяется совместно с опцией -т и имеет то же значение, что и со-
ответствующие КОНСТРУКЦИИ В LOAD DATA INFILE.
• — f i r s t - s l a v e , -x. Блокирует все таблицы во всех базах данных.
• —flush-logs, -F. Сбрасывает буферы журналов сервера перед началом выгрузки
дампа. Следует иметь в виду, что если эта опция применяется совместно с — a l l -
databases (или -А), буферы журналов сбрасываются для каждой из выгружаемых
баз данных.
• —force, -f. Продолжает работу, даже если в процессе выгрузки произошла
ошибка SQL.
• —host=HM*_xocTa, -h имя_хоста. Выгружает дамп с сервера MySQL, находящего-
ся на указанном хосте (по умолчанию localhost).
• —lock-tables, -1. Блокирует все таблицы перед началом выгрузки дампа. Табли-
цы блокируются с помощью READ LOCK, чтобы разрешить параллельные вставки в
случае таблиц My ISAM.
Обратите внимание, что при выгрузке нескольких баз данных блокируются таблицы
для каждой базы по отдельности. Поэтому использование этой опции не гарантирует,
490 Глава 7. Клиентские программы и утилиты MySQL

что таблицы в файле дампа будут логически согласованы между базами данных.
Таблицы разных баз могут быть выгружены полностью в разном состоянии.
• —master-data. Эта опция подобна —first-slave, но также генерирует оператор
CHANGE MASTER TO, который заставит подчиненный сервер репликации начинать с
правильной позиции в бинарном журнале главного сервера, если вы используете
этот SQL-дамп главного сервера для настройки подчиненного.
• —no-create-db, -п. Эта опция подавляет операторы CREATE DATABASE /* 132312
IF NOT EXISTS*/ имя_базы_данных, которые в противном случае включаются в
дамп, если были указаны опции —databases или —all-databases.
• —no-create-info, -t. He пишет в дамп операторы CREATE TABLE, которые пере-
создают каждую выгружаемую таблицу.
• —no-data, -d. He выводит никакой информации из строк таблицы. Это полезно,
если необходимо получить дамп структур таблиц.
• —opt. Эта опция является сокращением; она имеет тот же смысл, что и сочетание
—quick —add-drop-table —add-locks —create-options —disable-keys
—extended-insert --lock-tables. Опция позволяет выполнить операцию вы-
грузки дампа быстро и сгенерирует файл, который может быть быстро загружен
на сервер MySQL. Начиная с MySQL 4.1, --opt используется по умолчанию, но
может быть отключена с помощью —skip-opt. Чтобы отключить только некото-
рые из опций, включаемых —opt, нужно использовать соответствующую форму
—skip. Например, —skip-add-drop-table или —skip-quick.
• — password [^пароль], -р[пароль]. При подключении к серверу использует ука-
занный пароль. Имейте в виду, что если вы указываете краткую форму этой опции
(-р), то не должны оставлять пробел между названием опции и паролем. Если в
командной строке пароль не указан, он будет запрошен интерактивно.
• —рогt=HOMep_nopта, -Р номер__порта. Номер порта TCP/IP для подключения.
• —protocol={TCP I SOCKET | PIPE | MEMORY}. Сетевой протокол для подключе-
ния к серверу. Эта опция введена в MySQL 4.1.
• —quick, -q. Эта опция применима для выгрузки больших таблиц. Она заставляет
mysqldump извлекать строки для дампа по одной, вместо того чтобы извлечь сразу
весь результирующий набор и поместить его в буфер в памяти перед записью в дамп.
• --quote-names, -Q. Помещает имена баз данных, таблиц и столбцов в кавычки ' N '.
Если SQL-режим сервера включает опцию ANSI_QUOTES, имена помещаются в
двойные кавычки. Начиная с MySQL 4.1.1, опция —quote-names включена по
умолчанию.
• —result-file=$awi, -r файл. Направляет вывод в указанный файл. Эта опция
должна использоваться в Windows, поскольку она предохраняет символ новой
строки с \п' от преобразования в '\г\п' (перевод строки, возврат каретки).
• —single-transaction. Эта опция выдает SQL-оператор BEGIN перед выгрузкой
данных с сервера в дамп. В основном она применима с таблицами innoDB и уров-
нем изоляции транзакций READ COMMITED, так как в этом режиме она выгружает
базу данных в непротиворечивом состоянии, в котором база была на момент
BEGIN, без блокировки других приложений.
7.8. Программа резервного копирования баз данных mysqldump 491

При использовании этой опции вы должны помнить, что только транзакционные


таблицы будут выгружены в согласованном состоянии. Например, все таблицы
MylSAM или HEAP в процессе выгрузки с этой опцией могут изменять свое состояние.
Опция —single-transaction была добавлена в версии MySQL 4.O.2. Эта опция и
—lock-tables являются взаимоисключающими, поскольку LOCK TABLES подразу-
мевает неявную фиксацию всех незавершенных транзакций.
• —socket=nyTb, -S путь. Файл сокета, используемый для подключения к
localhost (хост по умолчанию).
• —tab=nyrb, -T путь. Генерирует файл данных с разделителями-табуляциями. Для
каждой выгружаемой в дамп таблицы mysqldump создает файл имя_таблицы. sql,
который содержит оператор CREATE TABLE, и файл имя_таблицы. txt, который со-
держит данные. Значение опции - это имя каталога, в который должны сохра-
няться эти файлы.
По умолчанию файлы данных .txt форматируются с использованием символа та-
буляции для разделения столбцов и символа новой строки для разделения строк
таблицы. Формат может быть переопределен явно с помощью опций —f ields-
ххх и —lines-xxx.
i На заметку!
j? Эта опция может использоваться, только если mysqldump запускается на той же машине, на ко-
Щ торой работает mysqld. Вы должны использовать учетную запись MySQL с привилегией FILE, a
Ж сервер должен иметь право записи в каталог, указанный в значении опции.

• --tables. Перекрывает опцию --databases или -В. Все аргументы, следующие за


этой опцией, трактуются как имена таблиц.
• —изег=имя_пользователя, -и имя__пользователя. Указывает имя пользователя
MySQL для подключения к серверу.
• --verbose, -v. Режим расширенных сообщений. Выводит информацию о ходе ра-
боты программы.
• —version, -V. Выводит информацию о версии и завершает работу.
• —where='условие_т*/пеге', -w у условие_where*. Выгружает только те строки, ко-
торые удовлетворяют заданному условию WHERE. Имейте в виду, что кавычки во-
круг аргумента обязательны, если он включает в себя пробелы и символы, вос-
принимаемые вашим командным интерпретатором как специальные.
Примеры:
"—where=user='jimf'"
"-wuserid>l"
"-wuserickl"
• —xml, -X. Записывает дамп в виде правильного XML-кода.
Можно также установить следующие переменные с помощью опции —имя_переменноРг=
значение:
• max_allowed_packet. Максимальный размер буфера для клиент-серверных ком-
муникаций. Значение переменной могло составлять до 16 Мбайт в версиях
MySQL до 4.0 и до 1 Гбайт - в версиях от 4.0 и выше.
492 Глава 7. Клиентские программы и утилиты MySQL

При генерации многострочных операторов вставки (при указании опции


--extended-insert или --opt), mysqldump создает строки длиной до
max_allowed_packet. Если вы увеличиваете значение этой переменной, то должны
убедиться, что переменная max_allowed_packet на сервере имеет, по меньшей ме-
ре, такое же значение.
• n e t b u f fer_length. Начальный размер буфера для клиент-серверных коммуника-
ций.
Существует также возможность установки значений переменных с использованием
синтаксиса —set-var 1аЫе=имя__переменной=значение или -О имя_переменной= значение.
Однако, начиная с версии MySQL 4.0, этот синтаксис считается устаревшим.
Вероятно, наиболее часто mysqldump применяется для полной выгрузки всех баз дан-
ных:
shell> mysqldump —opt имя__бавыжданных > backup-file. sql
Загрузить дамп обратно на сервер можно так:
shell> mysql имя_базы_данных < backup-file.sql
или
shell> mysql -e "source /путь-к-резервяым-колиям/backup-file. sql" имя_базы__данных
mysqldump также очень удобен для наполнения базы данными посредством копирова-
ния данных с одного сервера MySQL на другой:
shell> mysqldump —opt имя_базы_данных | mysql —hosЬ=удаленный-хост -С \
имя_ б а зы__да иных

Можно выгрузить дамп нескольких баз одной командой:


shell> mysqldump —databases имя_базы_данных1 [имя_базы_данных2 . . . ] > \
my__databases. sql
Если вы хотите выгрузить все базы данных, укажите опцию —all-databases:
shell> mysqldump —all-databases > all_databases.sql
Дополнительную информацию о создании резервных копий можно найти в разделе
4.6.1.

7.9. Программа резервного копирования


базы данных mysqhotcopy
mysqhotcopy - это сценарий на языке Perl, который использует LOCK TABLES, FLUSH
TABLES и ср либо scp для быстрого создания резервной копии базы данных. Это самый
быстрый способ получить копию базы данных или отдельных таблиц, однако он может
применяться только на той же машине, где расположены каталоги баз данных.
mysqhotcopy работает только для резервного копирования таблиц My ISAM и ISAM в среде
Unix и, начиная с MySQL 4.0.18, в среде NetWare.
shell> mysqlhotcopy имя_базы_данных [/путь/к/новому_каталогу)
shell> mysqlhotcopy имя_базы_данных_1...имя_базы_данных_п /путь/к/новому_каталогу
shell> mysqlhotcopy имя_базы_данных./регулярное_выражение/
mysqhotcopy поддерживает следующие опции:
7.10. Программа импорта данных mysqlimport 493

• — h e l p , - ? . Выводит справочное сообщение и завершает работу.


• —allowold. He прерывает работу, если целевой файл уже существует (переиме-
новывается с добавлением суффикса _old).
• —сЬескро1^=имя_базы_даняых.имя_таблицы. Вставляет контрольные точки в
указанной таблице имя_базы_данных. имя_таблицы.
• —debug. Разрешает вывод отладочной информации.
• —dryrun, -n. Сообщает о действиях без их выполнения.
• — f l u s h l o g . Сбрасывает буферы журналов после того, как все таблицы заблоки-
рованы.
• —keepold. He удаляет предыдущий (переименованный) целевой файл после
окончания работы.
• —method=#. Метод копирования (ср или scp).
• — n o i n d i c e s . He включает в резервную копию индексные файлы. Это делает ее
меньше и быстрее. Индексы могут быть пересозданы позже с помощью myisamchk
- r q или isamchk -rq.
• —password[=лароль], -р[пароль]. При подключении к серверу использует ука-
занный пароль. Имейте в виду, что в отличие от других клиентов MySQL, эта оп-
ция должна быть указана обязательно.
• —port=HOMep_nopra, -P номер_ пор та. Номер порта TCP/IP для подключения.
• — q u i e t , -q. Молчаливый вывод, за исключением случаев возникновения ошибок.
• --гедехр=выражеяие. Копирует все базы данных с именами, соответствующими
регулярному выражению выражение.
• —socket=nyTb, -S путь. Файл сокета Unix, используемый для подключения.
• —suf f ±х=строка. Суффикс имен копируемых баз данных.
• — tmpdir=nyTb. Каталог временных файлов (вместо /tmp).
• —изег=имя_пользователя, -и имя__пользователя. Указывает имя пользователя
MySQL для подключения к серверу.
mysqhotcopy читает группы опций [ c l i e n t ] и [mysqhotcopy] из конфигурационных
файлов.
Чтобы выполнить mysqhotcopy, вы должны иметь доступ к файлам таблиц, которые
собираетесь копировать, привилегию SELECT для этих таблиц и привилегию RELOAD (что-
бы иметь возможность выполнить FLUSH TABLES).
Воспользуйтесь p e r l d o c для просмотра дополнительной документации по
mysqhotcopy:
shell> perldoc mysqlhotcopy

7.10. Программа импорта данных mysqlimport


Клиентская программа mysqlimport предоставляет интерфейс командной строки для
SQL-оператора LOAD DATA INFILE. Большинство опций mysqlimport непосредственно
отображаются на конструкции оператора LOAD DATA INFILE.
494 Глава 7. Клиентские программы и утилиты MySQL

Вызов mysqlimport выглядит следующим образом:


shell> mysqlimport [опции] жя_базы_данных текстовый^файл! [текстовый_файл2...]
Для каждого текстового файла, перечисленного в командной строке, mysqlimport
удаляет расширение и использует результат для определения имени таблицы, в которую
нужно импортировать его содержимое. Например, файлы с именами p a t i e n t . t x t ,
p a t i e n t . t e x t и p a t i e n t все будут импортированы в таблицу p a t i e n t ,
mysqlimport поддерживает следующие опции:
• — h e l p , - ? . Выводит справочное сообщение и завершает работу.
• —colитпэ=список_столбцов, -с список^столбцов. Задает список столбцов, раз-
деленных запятыми. Порядок имен столбцов определяет соответствие между
столбцами файла данных и столбцами таблицы.
• —compress, -С. Сжимает всю информацию, пересылаемую между клиентом и
сервером, если оба поддерживают сжатие.
• —debug [=опции_отладки], -# [опции__отладки]. Записывает журнал отладки.
Обычно строка опции_отладки имеет формат ' d: t : о, имя_файла'.
• — d e l e t e , -D. Очищает таблицу перед импортом данных.
• —fields-terminates-by=...
—fields-enclosed-by=...
—fields-optionally-enclosed-by=...
—fields-escaped-by=...
—fields-terminated-by=...
Эта опция применяется совместно с опцией -т и имеет то же значение, что и со-
ответствующие конструкции В LOAD DATA INFILE.
• — f o r c e , -f. Игнорирует ошибки. Например, если таблица для отдельного тексто-
вого файла не существует, продолжает обрабатывать остальные файлы. Без этой
опции при возникновении ошибки работа немедленно завершается.
• —host=HM#_xoccra, -h имя_хоста. Импортирует данные на сервер MySQL на ука-
занном хосте (по умолчанию l o c a l h o s t ) .
• — i g n o r e , - i . См. описание опции — r e p l a c e .
• — i g n o r e - l i n e s = n . Игнорирует первые л строк файла данных.
• — l o c a l , -L. Читает входные файлы с клиента. По умолчанию предполагается, что
текстовые файлы находятся на сервере, если вы подключаетесь к l o c a l h o s t (хост
по умолчанию).
• - - l o c k - t a b l e s , - 1 . Блокирует по записи все таблицы перед обработкой текстовых
файлов. Это гарантирует, что все таблицы будут синхронизированы на сервере.
• —password[=пароль], -р[пароль]. При подключении к серверу использует ука-
занный пароль. Имейте в виду, что если вы указываете краткую форму этой опции
(-р), то не должны оставлять пробел между названием опции и паролем. Если в
командной строке пароль не указан, он будет запрошен интерактивно.
• — рог1=номер_портаг -Р номер_порта. Номер порта TCP/IP для подключения.
• —protocol={TCP I SOCKET | PIPE | MEMORY}. Сетевой протокол для подключе-
ния к серверу. Эта опция введена в MySQL 4.1.
7.11. Программа просмотра баз данных, таблиц и столбцов mysqlshow 495

• --replace, -г. Опции —replace и —ignore управляют поведением при загрузке


записей, которые дублируют существующие в таблице по значению уникальных
ключей. Если указать --replace, новые строки заменяют существующие с тем же
значением уникального ключа. Если указать —ignore, дублированные строки
пропускаются. Если не указывать ни одну из этих опций, то при возникновении
ошибки, связанной с обнаружением дублированного значения уникального клю-
ча, остаток файла игнорируется.
• —silent, -s. Режим минимального количества сообщений. Генерирует вывод
только при возникновении ошибок.
• —socket=nyrb, -S путь. Файл сокета, используемый для подключения.
• —изег=имя_пользователя, -и имя__пользователя. Указывает имя пользователя
MySQL для подключения к серверу.
• —verbose, -v. Режим расширенных сообщений. Выводит информацию о ходе ра-
боты программы.
• —version, -V. Выводит информацию о версии и завершает работу.
Ниже представлен пример сеанса работы mysqlimport:
shell> mysql -e 'CREATE TABLE imptest(id INT, n VARCHAR(30))' test
shell> ed
a
100 Max Sydow
101 Count Dracula

w imptest.txt
32
q
shell> od -c imptest.txt
0000000 1 0 0 \ t M a x S y d o w \ n1 0
0000020 1 \ t C o u n t D r a c u l a \ n
0000040
shell> mysqlimport —local test imptest.txt
test.imptest: Records: 2 Deleted: 0 Skipped: 0 Warnings: 0
shell> mysql -e 'SELECT * FROM imptesf test

I id |n I
+ + +
I 100 | Max Sydow |
I 101 | Count Dracula |
+ + +

7.11. Программа просмотра баз данных, таблиц


и столбцов mysqlshow
Клиентская программа mysqlshow может использоваться для быстрого просмотра
имеющихся на сервере баз данных, их таблиц, столбцов таблиц и индексов.
mysqlshow предоставляет интерфейс командной строки к некоторым SQL-операторам
SHOW. Та же информация может быть получена непосредственным вызовом этих опера-
торов, например, из программы mysql.
496 Глава 7. Клиентские программы и утилиты MySQL

Вызов mysqlshow выглядит следующим образом:


shell> mysqlshow [опции] [имя_базы_данных [имя_таблицы [имя_столбца]]]
• Если не указана ни одна база данных, показываются все.
• Если не указана ни одна таблица, показываются все таблицы в базе данных.
• Если не указан ни один столбец, показываются все соответствующие столбцы
таблицы вместе с их типами.
Имейте в виду, что в новейших версиях MySQL вы увидите только те базы, таблицы
или столбцы, для доступа к которым у вас имеются соответствующие привилегии.
Если последний аргумент содержит шаблонные символы SQL или командной оболоч-
ки ('*','?','%' или '_'), показываются только те имена, которые соответствуют шаблону.
Если имя базы данных содержит знаки подчеркивания, перед ними должны помещаться
обратные косые черты (некоторые оболочки Unix также требуют этого), чтобы получить
правильный список таблиц и столбцов. Символы '*' и '?' преобразуются в шаблонные
символы SQL '%' и '_'. Это может привести к некоторым недоразумениям, если вы захоти-
те вывести столбцы таблиц с символом '_' в имени, поскольку в этом случае mysqlshow
покажет только имена таблиц, соответствующие шаблону. Это легко исправить, добавив
дополнительный символ '%' в конец командной строки как отдельный аргумент.
mysqlshow поддерживает следующие опции:
• --help, -?. Выводит справочное сообщение и завершает работу.
• —character-sets-dir=nyTb. Каталог, в котором установлен символьный набор.
См. раздел 4.7.1.
• —compress, -С. Сжимает всю информацию, пересылаемую между клиентом и
сервером, если оба поддерживают сжатие.
• —debug [=опции_отладки], -# [опции_отладки]. Записывает журнал отладки.
Обычно строка опции_отладкиимеет формат 'd: t:о,имя_файла'.
• —default-character-set=на б ор. Использует набор в качестве набора символов
по умолчанию. См. раздел 4.7.1.
• ~host=MM£_xocTa, -h имя_хоста. Подключается к серверу MySQL на указанном хосте.
• —keys, -к. Показывает индексы таблиц.
• --password[=пароль], -р[ пароль]. При подключении к серверу использует ука-
занный пароль. Имейте в виду, что если вы указываете краткую форму этой опции
(-р), то не должны оставлять пробел между названием опции и паролем. Если в
командной строке пароль не указан, он будет запрошен интерактивно.
• —port=HOMep_nopra, -P номер_порта. Номер порта TCP/IP для подключения.
• --protocol={TCP | SOCKET | PIPE | MEMORY}. Сетевой протокол для подключе-
ния к серверу. Эта опция введена в MySQL 4.1.
• —socket=nyib, -S путь. Файл сокета, используемый для подключения.
• —status, -i. Показывает дополнительную информацию о каждой таблице.
• —изег=имя_пользователя, -и имя_пользователя. Указывает имя пользователя
MySQL для подключения к серверу.
• —verbose, -v. Режим расширенных сообщений. Выводит информацию о ходе ра-
боты программы. Эту опцию можно указать несколько раз, что приводит к боль-
шему и большему объему вывода.
7.13. Утилита замены строк replace 497

• —version, -V. Выводит информацию о версии и завершает работу.

7.12. Утилита объяснения кодов ошибок perror


Для большинства системных ошибок в дополнение к внутреннему сообщению
MySQL показывает системный код ошибки в одном из следующих стилей:
сообщение ... (errno: #)
сообщение ... (Errcode: #)
Узнать, что означает код ошибки можно либо заглянув в документацию по системе,
либо воспользовавшись утилитой perror.
perror печатает описание кода системной ошибки или кода ошибки механизма хра-
нения. Вызов perror осуществляется следующим образом:
s h e l l > perror [опции] код_ошибки . . .
Пример:
shell> perror 13 64
Error code 13: Permission denied
Error code 64: Machine is not on the network
Имейте в виду, что значение сообщений о системных ошибках может зависеть от ва-
шей операционной системы. Данный код ошибки может означать разные вещи в различ-
ных операционных системах.

7.13. Утилита замены строк replace


Утилита replace заменяет строки в файлах или в стандартном потоке ввода. Она ис-
пользует механизм конечного автомата для поиска самой длинной подходящей строки.
Эту утилиту можно использовать для того, чтобы менять местами фрагменты строк. На-
пример, следующая команда меняет местами а и b в заданных файлах f i l e l и f ile2:
shell> replace a b b a — f i l e l f i l e 2 ...
Используйте опцию — для того, чтобы отметить, где завершается список заменяемых
строк и начинается список файлов.
Любой файл, указанный в командной строке, модифицируется на месте, поэтому вам
может понадобиться создать копию исходного файла, прежде чем преобразовывать его.
Если никаких файлов в командной строке не указано, replace читает из стандартного
ввода и пишет в стандартный вывод. В этом случае опция — не нужна.
Утилита replace используется в msql2mysql и поддерживает следующие опции:
• -?, - I . Выводит справочное сообщение и завершает работу.
• -# опции_отладки. Записывает журнал отладки. Обычно строка опции_отладки
имеет формат ' d: t : о, имя_файла'.
• -s. Режим минимального количества сообщений. Печатает минимум информации
о том, что делает программа.
• -v. Режим расширенных сообщений. Печатает больший объем информации о том,
что делает программа.
• -V. Выводит информацию о версии и завершает работу.
8

Механизмы хранения и
типы таблиц в MySQL

M ySQL поддерживает несколько механизмов хранения, посредством которых осу-


ществляется управление таблицами различных типов. Механизмы хранения дан-
ных в MySQL могут выполнять обработку как транзакционных таблиц, так и таблиц без
транзакций:
• Первоначальным механизмом хранения был ISAM, посредством которого осуще-
ствлялась обработка нетранзакционных таблиц. Впоследствии он был заменен
механизмом My ISAM и со временем должен вообще выйти из употребления. В вер-
сии MySQL 4.1 его использование было сведено к минимуму, а в версии MySQL
5.0 он будет исключен полностью.
• В версии MySQL 3.23.0 были введены механизмы хранения данных MylSAM и
HEAP. Механизм MylSAM представляет собой усовершенствованный вариант меха-
низма ISAM. Механизм HEAP работает с так называемыми "таблицами в памяти"
(in-memory table). В версии MySQL 3.23.25 был представлен механизм MERGE, ко-
торый позволяет работать с совокупностью идентичных таблиц MylSAM как с од-
ной целой таблицей. Каждый из этих трех механизмом хранения работает с не-
транзакционными таблицами и включен в MySQL по умолчанию. В настоящее
время механизм HEAP имеет название MEMORY.
• Механизмы хранения innoDB и BDB, осуществляющие обработку транзакционных
таблиц, появились в версиях MySQL 3.23. Оба механизма доступны в исходном
дистрибутиве MySQL 3.23.34а. Механизм BDB включен в бинарные дистрибутивы
MySQL-Max для тех операционных систем, которые его поддерживают. Меха-
низм InnoDB также входит в состав бинарных дистрибутивов MySQL-Max для
MySQL 3.23. Начиная с версии MySQL 4.0, механизм InnoDB включен во все би-
нарные дистрибутивы. В исходных дистрибутивах вы можете включить или от-
ключить любой механизм, конфигурируя MySQL так, как это необходимо.
В настоящей главе вы сможете найти описание каждого механизма хранения MySQL,
кроме InnoDB, которому посвящена вся глава 9.
При создании новой таблицы вы можете сообщить MySQL о том, какой тип таблицы
должен быть выбран. Для этого в операторе CREATE TABLE необходимо добавить опцию
ENGINE ИЛИ TYPE:
8.1. Механизм хранения MylSAM 499

CREATE TABLE t (i INT) ENGINE = INNODB;


CREATE TABLE t (i INT) TYPE = MEMORY;
Опция ENGINE более предпочтительна, однако ее нельзя использовать в версиях
MySQL, предшествующих 4.0.18. Опцию TYPE можно использовать в любой версии, на-
чиная с MySQL 3.23.0 - первой версии MySQL, в которой появилась возможность рабо-
тать с несколькими механизмами хранения.
Если опустить опцию ENGINE или TYPE, по умолчанию будет выбрана таблица My ISAM.
Таблицу, которая будет использоваться по умолчанию, можно указать в системной пе-
ременной table_type.
Чтобы преобразовать таблицу одного типа в другой используется оператор ALTER
TABLE, который позволяет определить новый тип таблицы:
ALTER TABLE t ENGINE = MYISAM;
ALTER TABLE t TYPE = BDB;
Если вы попытаетесь использовать ^скомпилированный или скомпилированный, но
не активизированный механизм хранения, MySQL выберет вместо него My ISAM. Это бу-
дет удобно в том случае, если вам понадобится копировать таблицы между серверами
MySQL, которые поддерживают различные механизмы хранения данных. (Например, во
время настройки репликации главный сервер будет поддерживать транзакционные ме-
ханизмы для безопасного хранения данных, а подчиненный сервер - нетранзакционные
механизмы хранения в целях повышения скорости работы.)
Следует отметить, что автоматическая замена таблицы на My ISAM может сбить с тол-
ку начинающих пользователей MySQL. В версии MySQL 4.1 и выше при автоматиче-
ском изменении типа таблицы генерируется предупреждающее сообщение.
MySQL всегда создает файл формата . f rm, в котором содержится описание таблицы
и столбцов. Индексы таблиц и данные могут храниться в одном или нескольких других
файлах, что зависит от типа таблицы. Сервер создает файл . f rm над уровнем механизма
хранения. Каждый механизм хранения данных создает дополнительные файлы, необхо-
димые для таблиц, с которыми они работают.
База данных (БД) может содержать таблицы различных типов.
Если провести сравнение между таблицами без транзакций (Non-Transaction-Safe
Table - NTST) и транзакционными таблицами (Transaction-Safe Table - TST), то можно
выявить некоторые преимущества последних:
• Более безопасные. Даже при аварийном отказе MySQL или возникновении серь-
езных проблем с оборудованием вы сможете восстановить свои данные либо из
резервной копии и журнала транзакций, либо с помощью автоматического вос-
становления.
• Допускается комбинирование нескольких операторов и принятие их с помощью од-
ного оператора COMMIT (при условии, что режим автоматической фиксации отключен).
• Допускается выполнение оператора ROLLBACK для отмены произведенных измене-
ний (при условии, что режим автоматической фиксации отключен).
• Если произошел сбой при обновлении, вы сможете восстановить все произведен-
ные изменения. (В таблицах без транзакций произведенные изменения не могут
быть отменены.)
• Механизмы хранения с транзакциями лучше справляются с параллельной обработ-
кой таблиц, в которых одновременно с чтением выполняется обновление данных.
500 Глава 8. Механизмы хранения и типы таблиц в MySQL

Учтите, что для того чтобы использовать механизм хранения innoDB в MySQL 3.23, по-
требуется сконфигурировать, по крайней мере, опцию запуска innodb_data_file_path.
В версии 4.0, а также в более новых версиях механизм хранения InnoDB использует оп-
ции конфигурации, принятые по умолчанию (если только вы не определите свои опции).
См. раздел 9.4.
Таблицы без транзакций обладают своими преимуществами, что объясняется именно
отсутствием транзакций:
• Более высокая скорость работы.
• Меньшие требования к дисковому пространству.
• Для выполнения обновлений требуется меньше памяти.
В одних и тех же операторах можно комбинировать таблицы с транзакциями и таб-
лицы без транзакций, что дает возможность пользоваться преимуществами таблиц обеих
типов. Однако если для транзакции отключить режим автоматической фиксации, то из-
менения в таблицах без транзакций все равно будут мгновенно фиксироваться, без воз-
можности выполнения отката.

8.1. Механизм хранения MylSAM


В версии MySQL 3.23 механизм хранения My ISAM используется по умолчанию. Он
был создан на основе кода ISAM со множеством полезных расширений.
Каждая таблица My ISAM хранится на диске в трех файлах, имена которых начинаются
с имени таблицы, а расширения указывают на тип файла. В файле . f rm хранится описа-
ние таблицы, данные содержатся в файле с расширением .MYD (MYData), а индексный
файл имеет расширение .MYI (MYIndex).
Чтобы указать явным образом, что вам необходима таблица My ISAM, используйте оп-
цию ENGINE ИЛИ TYPE:
CREATE TABLE t (i INT) ENGINE = MYISAM;
CREATE TABLE t (i INT) TYPE = MYISAM;
Обычно эти опции не являются необходимыми. Механизм My ISAM используется по
умолчанию, что можно изменить в соответствующих настройках.
Выполнить проверку или восстановить таблицу My ISAM можно с помощью утилиты
myisamchk (см. раздел 4.6.2.7). Утилита myisampack позволяет сжать таблицу MylSAM,
уменьшая ее размеры (см. раздел 7.2).
По сравнению со старым механизмом хранения ISAM механизм MylSAM обладает це-
лым рядом усовершенствований:
• Все значения сохраняются с первым младшим байтом, в результате чего данные
не зависят от используемой операционной системы и компьютера. Чтобы данные
можно было переносить в двоичном формате, компьютер должен уметь опериро-
вать с числами со знаками, представленными в дополнительном двоичном коде
(как и во всех компьютерах, выпущенных в течение последних двадцати лет), и
должен поддерживать формат с плавающей запятой IEEE (этот формат также ис-
пользуется в подавляющем большинстве выпускаемых ныне серийных компьюте-
ров). Следует иметь в виду, что двоичную совместимость могут не поддерживать
лишь встроенные системы со специфическими процессорами.
8.1. Механизм хранения MylSAM 501

Хранение данных с первым младшим байтом не приводит к существенному сни-


жению скорости работы; байты в строках таблицы обычно не выровнены, и на
чтение такого байта в прямой и обратной последовательности потребуется одина-
ковый объем вычислительной работы. Кроме этого, чтобы извлечь значение из
столбца, потребуется не больше времени, чем на выполнение какой-нибудь дру-
гой операции.
• Поддерживаются файлы, имеющие большой размер (вплоть до файлов с 63-
разрядной длиной); это относится к тем файловым и операционным системам, ко-
торые поддерживают файлы большого размера.
• При одновременном удалении, обновлении и вставке данных строки с динамиче-
ски изменяющимся размером будут менее фрагментированными. Это объясняется
автоматическим комбинированием смежных удаленных блоков и расширением
блоков при удалении смежного блока.
• Максимальное количество индексов в таблице составляет 64 (до выхода версии
MySQL 4.1.2 их было 32). Количество индексов можно изменить путем повторной
компиляции. Максимальное количество столбцов в индексе равно 16.
• Максимальная длина ключа составляет 1000 байт (до выхода версии MySQL 4.1.2
она равнялась 500). Длину ключа можно изменить путем повторной компиляции.
В случае если длина ключа превышает 250 байт, используется больший размер
блока ключа (более 1024 байт).
• Допускается индексирование столбцов BLOB и TEXT.
• В индексированных столбцах допускается хранение значений NULL. В каждом
ключе для этого отводится 0-1 байт.
• Значения цифровых ключей хранятся с первым старшим байтом, благодаря чему
возможно более эффективное сжатие индексов.
• Индексные файлы в My ISAM имеют обычно меньший размер, чем в ISAM. Таким
образом, в общем случае My ISAM будет использовать меньший объем системных
ресурсов, нежели ISAM, хотя при добавлении данных в сжатый индекс механизме
My ISAM понадобится больше процессорного времени.
• Во время вставки записей в сортированном порядке (как в случае использования
столбца AUTOINCREMENT) дерево индексов разбивается таким образом, чтобы
верхний узел содержал всего лишь один ключ. За счет этого достигается более
эффективное использование пространства в дереве индексов.
• В пределах одной таблицы обрабатывается один столбец AUTO_INCREMENT. Этот
столбец механизм My ISAM автоматически обновляет при выполнении операторов
INSERT/UPDATE, В результате чего работа со столбцом AUTO_INCREMENT происходит
быстрее (как минимум на 10%). Удаленные из вершины последовательности зна-
чения повторно не используются, как это происходит в механизме ISAM. (Удален-
ные значения могут быть использованы повторно, если столбец AUTO_INCREMENT
будет определен как последний столбец.) Значение AUTO_INCREMENT можно обну-
лить С ПОМОЩЬЮ ALTER TABLE ИЛИ myisamchk.
• Если в таблице нет свободных блоков в средней части файла данных, вы можете
добавить новые строки с помощью оператора INSERT одновременно с тем, как
другие потоки будут производить считывание данных из таблицы. (Такое добав-
502 Глава 8. Механизмы хранения и типы таблиц в MySQL

ление новых строк называется параллельной вставкой.) При удалении строки или
обновлении строки с динамически изменяющейся длиной большим количеством
данных может возникнуть свободный блок. Если будут заняты (заполнены) все
свободные блоки, все последующие вставки вновь будут параллельными.
• Файл данных и индексный файл можно сохранять в различных каталогах, что
способствует повышению скорости работы (опции DATA DIRECTORY и INDEX
DIRECTORY ДЛЯ CREATE TABLE).

• В версии MySQL 4.1 каждый столбец символов может содержать символы в раз-
личных кодировках.
• Индексный файл My ISAM имеет флаг, который указывает на то, правильно ли была
закрыта таблица. Если для запуска использовать команду mysqld с опцией
--myisam-recover, тогда при открытии таблиц MylSAM будет выполняться автома-
тическая проверка (и восстановление в случае необходимости), если они не были
закрыты должным образом.
• Утилита myisamchk будет отмечать таблицы как проверенные, если использовать
опцию —update-state. Если указать опцию —fast, проверку пройдут только те
таблицы, которые не имеют такой пометки.
• С помощью опции —analyze утилита myisamchk будет сохранять статистические
данные по частям ключа, а не по всему ключу в целом, как в ISAM.
• Утилита myisamchk способна упаковывать столбцы BLOB и VARCHAR; утилита
pack_isam- нет.
Механизм хранения данных My ISAM обладает также рядом других возможностей, вос-
пользоваться которыми в MySQL можно будет в обозримом будущем:
• Поддержка типа VARCHAR; столбец VARCHAR начинается со значения длины, зани-
мающего два байта.
• Таблицы с VARCHAR могут иметь как фиксированную, так и динамически изме-
няющуюся длину записи.
• Столбцы VARCHAR и CHAR могут быть длиной до 64 Кбайт.
• Для UNIQUE может использоваться вычисленный хешированный индекс. Благодаря
этому вы сможете работать с UNIQUE в любой комбинации столбцов в таблице. (С
другой стороны, вы не сможете производить поиск по вычисленному индексу
UNIQUE.)

8.1.1. Опции запуска MylSAM


Для изменения поведения таблиц MylSAM используются следующие опции mysqld:
• —my is am- re cove г=режим. Режим автоматического восстановления поврежденных
таблиц MylSAM.
• —delay-key-write=ALL. Ключевые буферы не будут сбрасываться на диск между
записями для любой таблицы MylSAM.
| На заметку!
Ь В этом случае не следует использовать таблицы MylSAM из других программ (например, из дру-
% гого сервера MySQL или в утилите myisamchk) в процессе работы с таблицей. В противном слу-
f; чае произойдет искажение индекса.
8.1. Механизм хранения MylSAM 503

Опция —external-locking бесполезна для таблиц, в которых используется опция


—delay-key-write.
См. раздел 4.2.1.
На поведение таблиц My ISAM влияют следующие системные переменные:
• bulk_insert_buffer__size. Размер кэша дерева, используемого при оптимизации
групповой вставки.
р На заметку!
Ц Это ограничение распространяется на поток*

• myisam_max_extra_sort_file_size. Используется, чтобы помочь MySQL принять


решение относительно того, когда использовать медленный, но безопасный метод
создания индекса кэша ключей.
| На заметку!
& До версии MySQL 4.0.3 значение этой переменной указывалось в мегабайтах, а начиная с этой
Ц версии - в байтах.

• m y i s a m m a x s o r t f i l e s i z e . Для создания индекса не будет использоваться ме-


тод быстрой сортировки, если временный файл будет иметь размер больше, чем
размер, указанный в этой переменной.
Щ На заметку!
*/* До версии MySQL 4.0.3 значение этой переменной указывалось в мегабайтах, а начиная с этой
|% версии - в байтах.

• myisam_sort_buf fer_size. Устанавливает размер буфера, используемого при вос-


становлении таблиц.
См. раздел 4.2.3.
Автоматическое восстановление таблиц инициируется при запуске команды raysqld с
опцией —myisam-recover. В этом случае, когда сервер открывает таблицу MylSAM, он
проверяет, помечена ли данная таблица как поврежденная, отлично ли от нуля значение
переменной счетчика открытий и не производится ли запуск сервера с опцией —skip-
external-locking. Если одно из этих условий будет выполнено, произойдет следующее:
• Будет выполнена проверка таблицы на наличие ошибок.
• Если сервер обнаружит ошибку, он попытается выполнить быстрое восстановле-
ние таблицы (включая сортировку, но без повторного создания файла данных).
• Если восстановить таблицу не удалось вследствие ошибки в файле данных (на-
пример, из-за ошибки дублирования ключей), сервер еще раз попытается восста-
новить таблицу, однако на этот раз уже с повторным созданием файла данных.
• Если восстановить таблицу не удалось, сервер попытается сделать это еще раз с
помощью старого способа восстановления (выполняя построчную запись без сор-
тировки). Этот способ позволяет исправить ошибку любого рода и не требует
большого объема дискового пространства.
Если в процессе восстановления не удалось восстановить все строки из предыдущего
выполненного оператора, и в команде --myisam-recover не была указана опция FORCE, в
журнале ошибок появится следующее сообщение:
Error: Couldn't repair table: test.gOOpages
504 Глава 8. Механизмы хранения и типы таблиц в MySQL

Ошибка: Невозможно восстановить таблицу: test.gOOpages


Если указывалась опция FORCE, это сообщение будет выглядеть следующим образом:
Warning: Found 344 of 354 rows when repairing ./test/gOOpages
Предупреждение: найдено 344 из 354 строк во время восстановления ./test/gOOpages
Имейте в виду, что если для автоматического восстановления использовать опцию
BACKUP, то в процессе восстановления будут создаваться файлы, с именами в виде
имя_таблицы-дата-время .ВАК. Для автоматического переноса созданных файлов из ката-
логов базы данных на резервный носитель следует использовать сценарий сгоп.

8.1.2. Пространство, необходимое для ключей


В таблицах My ISAM используются индексы в форме В-деревьев. Приближенно оце-
нить размер индексного файла можно по формуле [длина_ключа+4) /0.67, просуммиро-
ванной по всем ключам. Эта формула используется при наиболее неблагоприятном ва-
рианте, когда все ключи вставлены в отсортированном порядке и таблица не имеет сжа-
тых ключей.
В индексах строк сжаты пробелы. Если строкой является первая часть индекса, пре-
фикс также будет сжат* Сжимая пробелы, можно добиться еще большего сокращения
размеров индексного файла, чем с помощью приведенной выше формулы, если столбец
строки будет содержать множество пробелов в конце текстовой строки или будет яв-
ляться столбцом VARCHAR, который не всегда используется в полную длину. Сжатие пре-
фикса полезно выполнять, если множество строк будут содержать одинаковый префикс.
Числа в таблицах MylSAM могут быть сжаты в префиксах. Для этого при создании
таблицы необходимо указать PACK_KEYS=1. Это будет полезно при наличии множества
целочисленных ключей с одинаковыми префиксами, когда числа хранятся с первым
старшим байтом.

8.1.3. Форматы хранения данных в таблицах MylSAM


My ISAM поддерживает три различных формата хранения данных. Два из них (фикси-
рованный и динамический формат) выбираются автоматически в зависимости от типа
используемых столбцов. Третий формат, называемый сжатым форматом, можно создать
только с помощью утилиты myisampack.
Выполняя операторы CREATE или ALTER над таблицами, в которых отсутствуют
столбцы BLOB или TEXT, с помощью опции ROW_FORMAT можно указать формат таблицы
FIXED или DYNAMIC. В результате столбцы CHAR и VARCHAR станут столбцами CHAR для
формата FIXED или VARCHAR для формата DYNAMIC.
В дальнейшем можно будет сжимать или разворачивать таблицы, указывая для ко-
манды ALTER TABLE ОПЦИЮ ROW_FORMAT={COMPRESSED | DEFAULT}.

8.1.3.1. Характеристики статической таблицы


(таблицы с фиксированной длиной)
Статический формат в таблицах MylSAM является форматом по умолчанию. Он ис-
пользуется в тех случаях, когда таблица не содержит столбцов переменной длины
(столбцы VARCHAR, BLOB или TEXT). Каждая строка сохраняется с фиксированным количе-
ством байт.
8.1. Механизм хранения MylSAM 505

Среди трех форматов хранения данных в механизме My ISAM статический формат яв-
ляется самым простым и наиболее безопасным (данные в таблицах этого формата менее
всего подвержены искажению). Также он является наиболее быстрым среди форматов,
работающих с дисками. Повышение скорости работы достигается за счет простоты ал-
горитма поиска строк в файле данных, хранящемся на диске: для поиска строки в индек-
се ее номер умножается на длину строки. Кроме того, при сканировании таблицы очень
просто считывать постоянное число записей при каждой операции чтения с диска.
Безопасность таблицы можно будет оценить, если произойдет сбой в работе компью-
тера во время записи сервером MySQL файла My ISAM фиксированной длины. В этом слу-
чае утилита myisamchk сможет без труда определить начало и окончание каждой строки,
поэтому обычно с ее помощью можно восстановить все записи за исключением частич-
но перезаписанных. Имейте в виду, что индексы таблицы My ISAM всегда можно реконст-
руировать на основе строк данных.
К характеристикам таблиц статического формата можно отнести следующие:
• Все столбцы CHAR, NUMERIC и DECIMAL заполняются пробелами по всей ширине
столбца.
• Высокая скорость работы.
• Простота кэширования.
• Простота восстановления данных после сбоя (благодаря тому, что записи распо-
лагаются в фиксированных позициях).
• Не нуждаются в реорганизации данных кроме тех случаев, когда вы удаляете боль-
шое число записей и хотите передать освобожденное пространство диска операци-
онной системе. Для этого используется OPTIMIZE TABLE или myisamchk -r.
• Обычно требуют больше пространства на диске, чем таблицы динамического
формата.

8.1.3.2. Характеристики динамических таблиц


Динамический формат хранения используется в том случае, если таблица My ISAM со-
держит столбцы переменной длины (VARCHAR, BLOB или TEXT) или если таблица была соз-
дана с использованием опции ROW_FORMAT=DYNAMIC.
Этот формат немного сложнее, поскольку каждая строка имеет заголовок, в котором
указывается ее длина. Кроме того, одна запись может заканчиваться в нескольких пози-
циях, если длина строки увеличится в процессе обновления.
Для дефрагментации таблицы используется команда OPTIMIZE TABLE или утилита
myisamchk. Если имеются столбцы с фиксированной длиной, к которым вы часто обра-
щаетесь или которые часто изменяете в таблице, содержащей несколько столбцов пере-
менной длины, то чтобы предотвратить фрагментацию столбцов переменной длины их
следует переместить в другие таблицы.
К характеристикам таблиц динамического формата относятся следующие:
• Все столбцы со строками являются динамическими за исключением столбцов,
имеющих длину менее 4.
• Каждой записи предшествует битовая карта, указывающая на то, в каких столбцах
содержатся пустые строки (для столбцов со строками) или нули (для столбцов с
числами). Следует учесть, что это не относится к столбцам, содержащим значения
NULL. Если столбец со строками будет иметь нулевую длину после удаления про-
506 Глава 8. Механизмы хранения и типы таблиц в MySQL

белов в конце строки, или если столбец с числами будет иметь нулевое значение,
он будет отмечен в битовой карте и не будет сохранен на диск. Строка с содер-
жимым сохраняется в виде байта длины и ее содержимого.
• Для динамических таблиц обычно требуется меньше дискового пространства, чем
для таблиц статического формата.
• Каждая запись занимает столько пространства, сколько это необходимо. Однако
если запись становится большей, она разделяется на требуемое количество частей,
что в результате приводит к фрагментации записи. Так, если вы обновите строку
информацией, которая заполнит всю длину строки, строка окажется фрагменти-
рованной. В этом случае вам придется периодически выполнять команду
OPTIMIZE TABLE или запускать утилиту myisamchk с опцией -г, чтобы добиться
более высокой производительности. Статистику по таблице можно получить с
помощью утилиты myisamchk с опцией -ei.
• Восстанавливать таблицы динамического формата после сбоев труднее, чем ста-
тические таблицы, поскольку запись может оказаться фрагментированной и быть
разделена на множество частей; кроме этого, может отсутствовать ссылка (или
фрагмент).
• Длину строки для динамически изменяющихся записей можно приблизительно
оценить следующим образом:
3
+ {количество столбцов + 7) / 8
+ {количество столбцов с символами)
+ {упакованный размер столбцов с числами)
+ {длина строк)
+ {количество столбцов со значением NULL + 7) / 8
На каждую ссылку добавляется по 6 байт. Динамические записи связываются при
каждом увеличении записи в момент ее обновления. Каждая новая ссылка будет
иметь размер как минимум 20 байт, поэтому следующее увеличение можно будет
произвести по той же ссылке. В противном случае будет использоваться другая
ссылка. Количество ссылок можно узнать с помощью команды myisamchk -ed.
Удалить ссылки можно с помощью команды myisamchk -r.

8.1.3.3. Характеристики сжатых таблиц


Таблицы сжатого формата предназначены только для чтения и генерируются с по-
мощью инструмента myisampack.
Начиная с версии 3.23.19, дистрибутивы MySQL содержат инструмент myisampack.
(Эта версия MySQL регламентируется лицензией GPL.) В более ранних версиях инстру-
мент myisampack поставлялся только по лицензионному соглашению или соглашению о
поддержке; несмотря на это, сервер способен читать таблицы, сжатые с помощью
myisampack. Распаковать сжатые таблицы можно с помощью утилиты myisamchk. (В ме-
ханизме хранения данных ISAM сжатые таблицы можно создавать с помощью утилиты
pack_isam и распаковывать с помощью isamchk.)
Сжатые таблицы обладают следующими характеристиками:
• Занимают очень мало дискового пространства. Это позволяет сократить исполь-
зование диска, что будет полезно при работе с низкоскоростными дисками (таки-
ми, как приводы компакт-дисков).
8.1. Механизм хранения MylSAM 507

• Каждая запись сжимается отдельно, поэтому издержки при доступе сводятся к


минимуму. Заголовок для записи является фиксированным (1-3 байта), в зависи-
мости от размера самой большой записи в таблице. Сжатие каждого столбца про-
изводится по-разному. Обычно для каждого столбца используется отдельное де-
рево Хаффмана. Существует несколько типов сжатия:
• Сжатие пробелов суффикса.
• Сжатие пробелов префикса.
• Для хранения чисел с нулевым значением используется один бит.
• Если значения в столбце целых чисел представлены в небольшом диапазоне,
столбец сохраняется с использованием наименьшего по размерам типа. Напри-
мер, столбец BIGINT (восемь байт) можно хранить как столбец TINYINT (один
байт), если все его значения будут находиться в диапазоне от-128 до 127.
• Если столбец имеет только небольшую совокупность возможных значений,
тип столбца преобразовывается в ENUM.
• В столбце может использоваться сочетание вышеуказанных сжатий.
• Возможна обработка записей фиксированной и динамически изменяющейся длины.

8.1-4. Проблемы, связанные с таблицами MylSAM


Формат файлов, который MySQL использует для хранения данных, тестировался са-
мым тщательным образом, однако всегда существуют обстоятельства, которые могут
привести к искажению данных в таблицах базы.

8.1.4.1. Повреждения таблиц MylSAM


Несмотря на всю надежность формата таблиц MylSAM (все изменения в таблице, про-
изведенные с помощью оператора SQL, записываются до того, как оператор вернет зна-
чение), существует вероятность искажения данных в таблицах. Это может произойти в
следующих случаях:
• В процессе записи был уничтожен процесс mysqld.
• Произошло неожиданное отключение питания компьютера.
• Возникли ошибки оборудования.
• Для работы с таблицей, которая на данный момент модифицировалась сервером,
применялась внешняя программа (например, myisamchk).
• Возникла программная ошибка в коде MySQL или MylSAM.
Ниже представлены наиболее распространенные признаки повреждения таблицы:
• Во время извлечения данных из таблицы вы получили следующее сообщение об
ошибке:
Incorrect key f i l e for table: ' . . . ' . Try to repair i t
Неверный файл ключей для таблицы: ' . . . ' . Попытайтесь восстановить его
• Произведенные запросы не находят строки в таблице или возвращают неполные
данные.
Проверить состояние таблицы можно с помощью оператора CHECK TABLE. Восстанов-
ление поврежденной таблицы MylSAM выполняется командой REPAIR TABLE. Если про-
508 Глава 8. Механизмы хранения и типы таблиц в MySQL

цесс mysqld не запущен, вы можете также проверить или восстановить таблицу с помо-
щью myisamchk. См. раздел 4.6.2.1.
Если повреждение таблиц происходит слишком часто, попытайтесь установить при-
чину этого. Прежде всего, необходимо выяснить, связано ли повреждение таблиц со
сбоем на сервере. Просмотрите журнал ошибок: он должен содержать новое сообщение
restarted mysqld, свидетельствующее о том, что повреждение таблицы произошло
вследствие сбоя на сервере. Повреждение таблицы может произойти также во время вы-
полнения обычной операции, что свидетельствует о программной ошибке. В этом случае
желательно создать тестовый случай, с помощью которого можно было бы установить
причину неприятностей. См. раздел А.4.2.

8.1.4.2. Проблемы, связанные с неправильно закрытыми таблицами


Каждый индексный файл My ISAM (.MY I) имеет в своем заголовке счетчик, который
может быть использован для проверки правильности закрытия таблицы. Если при вы-
полнении команды CHECK TABLE или myisamchk вы получили следующее сообщение:
clients are using or haven't closed the table properly
клиенты неправильно используют таблицу или не закрыли ее соответствующим образом
значит, произошло нарушение синхронности счетчика. Это сообщение не обязатель-
но свидетельствует о повреждении таблицы, однако вам все равно придется проверить
таблицу, чтобы убедиться в ее целостности.
Счетчик работает следующим образом:
• Во время первого обновления таблицы в MySQL значение счетчика в заголовках
индексных файлов увеличивается.
• При последующих обновлениях значение счетчика не изменяется.
• После того как будет закрыт последний экземпляр таблицы (после выполнения
операции FLUSH TABLES или по причине отсутствия места в кэше таблицы), значе-
ние счетчика уменьшится, если в таблицу были внесены изменения.
• Если в процессе восстановления таблицы или в ходе ее проверки оказалось, что
таблица не содержит никаких ошибок, значение счетчика обнуляется.
• Чтобы избежать проблем с взаимодействием с другими процессами, которые мо-
гут проверять таблицу, значение счетчика при закрытии таблицы не уменьшается,
если оно было равно нулю.
Другими словами, синхронность счетчика может быть нарушена в следующих случаях:
• Таблицы My ISAM копируются без выполнения команд LOCK TABLES и FLUSH TABLES.
• Произошел сбой MySQL между обновлением и последним закрытием. (Имейте в
виду, что таблица может сохранять свою целостность, поскольку MySQL всегда
регистрирует изменения, произошедшие между выполнением операторов.)
• Таблица была модифицирована с помощью команд myisamchk --recover или
myisamchk --update-state в тот момент, когда она использовалась mysqld.
• Таблицу используют несколько серверов mysqld; один из серверов выполнил в
отношении таблицы команду REPAIR TABLE или CHECK TABLE, причем таблица в
этот момент использовалась другим сервером. В этом случае лучше всего выпол-
нить команду CHECK TABLE, даже если вы можете получить предупреждающее со-
8.2. Механизм хранения MERGE 509

общение от других серверов. Не следует применять команду REPAIR TABLE, по-


скольку о замене файла данных остальным серверам не будет известно.
Вообще говоря, лучше всего избегать общего использования каталога данных не-
сколькими серверами. Более подробно об этом вопросе рассказывалось в разделе 4.9.

8.2. Механизм хранения MERGE


Механизм хранения MERGE был впервые представлен в версии MySQL 3.23.25. Он из-
вестен также как механизм MRG__MyISAM. В настоящее время его код является достаточно
стабильным.
Таблица MERGE представляет собой совокупность таблиц, идентичных таблицам
My ISAM, которые могут использоваться как одна таблица. Здесь под "идентичными" таб-
лицами подразумеваются таблицы, имеющие одинаковую структуру и ключи. Вам не
удастся объединить таблицы, в которых по-разному упакованы столбцы, которые не
имеют одинаковых столбцов или имеют индексы различного порядка. Однако любую из
таких таблиц можно сжать с помощью утилиты myisampack. См. раздел 7.2.
В процессе создания таблицы MERGE MySQL создает на диске два файла. Имя файла
начинается с имени таблицы и имеет расширение, указывающее на тип файла. В файле
. frm хранится описание таблицы, а файл .MRG содержит имена таблиц, которые будут
использоваться как одна таблица. (Первоначально все используемые таблицы должны
были находиться в той же базе данных, что и таблица MERGE. Это ограничение было сня-
то в версии MySQL 4.1.1.)
Для таблиц, входящих в таблицу MERGE, можно использовать команды SELECT, DELETE,
UPDATE и (в версии MySQL 4.0) INSERT. Чтобы использовать возможности этих команд,
необходимо располагать соответствующими привилегиями на их выполнение в табли-
цах, входящих в таблицу MERGE.
Если вы примените к таблице MERGE команду DROP, вы удалите только определение
MERGE. Таблицы, входящие в состав MERGE, останутся нетронутыми.
При создании таблицы MERGE необходимо задать оператор UN ION=( список- та блиц), в
котором указывается, какие таблицы будут использоваться как одна. Если необходимо,
чтобы вставка в таблицу MERGE осуществлялась в первой или последней таблице списка
UNION, с помощью опции INSERT_METHOD можно указать метод вставки. Если не указать
эту опцию или не присвоить ей значение N0, то при попытке вставить записи в таблицу
MERGE возникнет ошибка.
В следующем примере показан пример создания таблицы MERGE:
mysql> CREATE TABLE t l (
-> a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> m e s s a g e CHAR(20));
mysql> CREATE TABLE t 2 (
-> a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> m e s s a g e CHAR(20));
mysql> INSERT INTO t l (message) VALUES ( ' T e s t i n g ' ) , ( ' t a b l e ' ) , ( ' t l • ) ;
mysql> INSERT INTO t2 (message) VALUES ('Testing•),('table'),('t2');
mysql> CREATE TABLE t o t a l (
-> a INT NOT NULL AUTO_INCREMENT,
-> m e s s a g e CHAR(20), INDEX(a))
-> TYPE=MERGE U N I O N = ( t l , t 2 ) INSERT METHOD=LAST;
510 Глава 8. Механизмы хранения и типы таблиц в MySQL

Обратите внимание на то, что в таблице MERGE столбец а имеет индекс, хотя и не объ-
явлен как PRIMARY KEY, подобно остальным таблицам My ISAM. Это объясняется тем, что
таблица MERGE не может обеспечить уникальность каждой таблицы, входящей в данную
совокупность.
После того как будет создана таблица MERGE, можно выполнить следующее действие:
mysql> SELECT * FROM total;
+—+ +
I a | message |
+—+ +
1 | Testing |
2 | table |
3 I tl |
1 | Testing |
2 | table |
3 I t2 I
+ + +
Обратите внимание на то, что манипулировать файлом .MRG можно и за пределами
сервера MySQL:
shell> cd /каталог_данных_тузд1/текущая_база_данных
shell> Is -1 tl t2 > total.MRG
shell> mysqladmin flush-tables
Чтобы создать новую совокупность таблиц My ISAM в таблице MERGE, необходимо вы-
полнить следующие действия:
• Выполните команду DROP и повторно создайте таблицу.
• С помощью команды ALTER TABLE имя_таблицы UNION= (...) измените список
таблиц, входящих в совокупность.
• Измените файл . MRG и выполните оператор FLUSH TABLE для таблицы MERGE и всех
ее таблиц, чтобы механизм хранения мог прочитать новый файл описания.
Ниже представлены возможности таблиц MERGE:
• Довольно простое управление совокупностью журнальных таблиц. Так, например,
можно ввести данные по различным месяцам в различные таблицы, сжать некото-
рые из них с помощью утилиты myisampack и затем создать таблицу MERGE, чтобы
использовать их как одну.
• Более высокая скорость работы. Можно разделить по некоторым критериям
большие таблицы формата только для чтения и сохранить получившиеся отдель-
ные таблицы на различных дисках. С такой таблицей MERGE можно будет работать
гораздо быстрее, чем с действительно одной большой таблицей. (Аналогичные
преимущества можно получить, используя дисковый массив RAID.)
• Более эффективный поиск данных. Если вы точно знаете, что ищете, тогда поиск
можно сделать по некоторым запросам в одной таблице, входящей в совокуп-
ность, а таблицу MERGE использовать для других запросов. Можно работать также
с множеством различных таблиц MERGE с перекрывающимися совокупностями
таблиц.
8.2. Механизм хранения MERGE 511

• Эффективное восстановление поврежденных таблиц. Гораздо легче восстановить


одну таблицу, входящую в состав MERGE, нежели восстанавливать одну действи-
тельно большую таблицу.
• Мгновенное формирование нескольких таблиц в виде одной. Для таблицы MERGE не
нужно поддерживать индекс, поскольку она работает с индексами каждой отдельной
таблицы. Как результат, можно очень быстро сформировать или переформировать со-
вокупности таблиц MERGE. (Учтите, что при формировании таблицы MERGE необходи-
мо давать определение индексов, даже если ни один из них не будет создан.)
• Если имеется совокупность таблиц, которые вы намерены объединить по требо-
ванию или во время формирования в одну большую таблицу, то лучше всего соз-
дать на их основе таблицу MERGE по требованию. Сделать это будет гораздо быст-
рее и, кроме того, вы сможете сэкономить довольно большую часть дискового
пространства.
• Таблицы MERGE позволяют обойти ограничение на размер файлов в данной опера-
ционной системе. Это ограничение распространяется на индивидуальную таблицу
My ISAM, а на совокупность таблиц My ISAM - нет.
• Для таблицы My ISAM можно создать псевдоним или синоним, определяя таблицу
MERGE, которая будет отображена для данной одиночной таблицы. Причем это
практически не скажется на производительности (добавится только пара непря-
мых вызовов и вызовы memcpy () при каждом считывании).
А вот недостатки таблиц MERGE:
• Для формирования таблицы MERGE можно использовать только идентичные таб-
лицы My ISAM.
• Таблицы MERGE используют большее количество описаний файлов. Если 10 клиен-
тов используют таблицу MERGE, объединяющую 10 таблиц, то сервер будет иметь
дело с (10* 10)+10 файловыми дескрипторами. (10 дескрипторов файлов данных
для каждого из 10 клиентов и 10 дескрипторов индексных файлов, являющихся
для клиентов общими.)
• Медленное чтение ключей. При считывании ключа механизм хранения MERGE
должен произвести чтение во всех таблицах, чтобы выяснить, какая из них наибо-
лее всего совпадает с данным ключом. Если затем попытаться выполнить чтение
следующего ключа, механизму MERGE придется просмотреть буферы чтения, что-
бы найти следующий ключ. Только после завершения просмотра одного буфера
механизм перейдет к просмотру следующего блока ключей. Вследствие этого ра-
бота с ключами MERGE осуществляется гораздо медленнее при поисках eq_ref, но
не очень медленно при поисках ref. Дополнительно о eq_ref и ref можно почи-
тать в разделе 6.2.1.

8.2.1. Проблемы, связанные с таблицами MERGE


При работе с таблицами MERGE могут возникать следующие проблемы:
• Если вы используете команду ALTER TABLE для преобразования таблицы MERGE в
таблицу другого типа, то отображение ее таблиц будет утрачено. Строки из ее
таблиц My ISAM будут скопированы в измененную таблицу, которой затем будет
присвоен новый тип.
512 Глава 8. Механизмы хранения и типы таблиц в MySQL

• До выхода версии MySQL 4.1.1 таблица MERGE и все ее таблицы должны были
храниться в одной и той же базе данных.
• Оператор REPLACE не работает.
• Нельзя выполнять операторы DROP TABLE, ALTER TABLE или DELETE FROM без кон-
струкции WHERE, a REPAIR TABLE, TRUNCATE TABLE, OPTIMIZE TABLE ИЛИ ANALYZE
TABLE для любой таблицы, входящей в состав таблицы MERGE, которая, в свою оче-
редь, является "открытой". Если вы попытаетесь выполнить один из упомянутых
операторов, таблица MERGE, вероятно, все еще будет ссылаться на исходную таб-
лицу, и вы получите непредсказуемые результаты. Самый простой способ реше-
ния этой проблемы заключается в выполнении оператора FLUSH TABLES, который
позволит проверить наличие "открытых" таблиц MERGE.
• Таблица MERGE не может поддерживать ограничения UNIQUE для всех своих таб-
лиц. При выполнении команды INSERT данные переносятся в первую или послед-
нюю таблицу My ISAM (в зависимости от значения, присвоенного опцией
INSERTMETHOD). MySQL гарантирует, что уникальные значения ключей остаются
уникальными в пределах данной таблицы My ISAM, но не во всех таблицах, входя-
щих в совокупность.
• До версии MySQL 3.23.49 оператор DELETE FROM таблица^тегде без конструкции
WHERE очищал только отображение для таблицы. Другими словами, вместо удале-
ния записей из отображенных таблиц она некорректно освобождала файл .MRG.
• Применение оператора RENAME TABLE к активной таблице MERGE может привести к
повреждению данных в таблице. Эта проблема будет решена в версии MySQL
4.1.x.
• Когда вы создаете таблицу MERGE, не выполняется проверка существования таб-
лиц, входящих в совокупность, и идентичности их структуры. Когда используется
таблица MERGE, MySQL быстро проверяет, равна ли длина записей во всех отобра-
женных таблицах, что, однако, не очень надежно. Если вы попытаетесь сформи-
ровать таблицу MERGE на основе разнородных таблиц My ISAM, вы наверняка
столкнетесь с проблемами.
• Порядок индексов в таблице MERGE и в ее таблицах должен быть одинаковым. Ес-
ли вы используете ALTER TABLE для добавления индекса UNIQUE в таблицу, входя-
щую в состав таблицы MERGE, и затем будете использовать ALTER TABLE для добав-
ления неуникального индекса в таблицу MERGE, то порядок индексов в таблицах
окажется различным, если в таблице, входящей в состав таблицы MERGE, оставался
старый неуникальный индекс. (Это происходит из-за того, что оператор ALTER
TABLE ставит индексы UNIQUE перед неуникальными индексами, чтобы можно бы-
ло выявлять дублированные ключи на самой ранней стадии их появления.) По-
этому запросы могут вернуть неожиданные результаты.
• Оператор DROP TABLE, выполненный над таблицей, входящей в состав таблицы
MERGE, не работает в среде Windows, поскольку механизм MERGE скрывает отобра-
жение таблиц от верхнего уровня MySQL. Так как в Windows не разрешается уда-
лять открытые файлы, то сначала необходимо будет сбросить на диск все таблицы
MERGE (с помощью FLUSH TABLES) или удалить таблицу MERGE, прежде чем удалить
таблицу. Эту ошибку мы планируем исправить с введением представлений.
8.3. Механизм хранения данных MEMORY (HEAP) 513

8.3. Механизм хранения данных


MEMORY (HEAP)
Механизм хранения данных MEMORY создает таблицы с содержимым, которые хранят-
ся в памяти компьютера. Начиная с версии MySQL 4.1, синонимом таблиц MEMORY явля-
ется HEAP, однако более предпочтительным считается термин MEMORY.
Каждая таблица MEMORY связана с одним дисковым файлом. Имя файла начинается с
имени таблицы и имеет расширение . f rm, указывающее на то, что в этом файле хранится
описание таблицы. Чтобы указать явным образом, что вам необходима таблица MEMORY,
используйте опцию ENGINE или TYPE:
CREATE TABLE t (i INT) ENGINE = MEMORY;
CREATE TABLE t (i INT) TYPE = HEAP;
Таблицы MEMORY хранятся в памяти компьютера и используют хешированные индек-
сы. Благодаря этому работа с ними производится очень быстро и их очень удобно при-
менять для создания временных таблиц. Однако существует и негативная сторона - в
случае сбоя в работе сервера все данные, хранящиеся в таблице MEMORY, будут утеряны.
Таблицы существуют благодаря их описаниям, хранящимся в файлах . f rm на диске, од-
нако после перезапуска сервера такие таблицы оказываются пустыми.
Ниже представлен пример создания, использования и удаления таблицы MEMORY:
mysql> CREATE TABLE t e s t TYPE=MEMORY
-> SELECT ip,SUM(downloads) AS down
-> FROM log_table GROUP BY ip;
mysql> SELECT COUNT(ip),AVG(down) FROM t e s t ;
mysql> DROP TABLE t e s t ;
Таблицы MEMORY обладают следующими характеристиками:
• Пространство для таблиц MEMORY распределяется по блокам небольшого размера.
Таблицы используют 100%-ное динамическое хеширование (при операциях
вставки). Для таблиц MEMORY не нужны области переполнения или дополнительное
пространство для ключей. Дополнительное пространство также не требуется и
для свободных списков. Удаленные строки помещаются в связанный список и по-
вторно используются при вставке в таблицу новых данных. Таблицы MEMORY также
не имеют проблем с одновременным удалением и вставкой, что часто случается в
хешированных таблицах.
• В таблице MEMORY может быть до 32 индексов в таблице, 16 столбцов в индексе, а
максимальная длина ключа может составлять 500 байт.
• До выхода версии MySQL 4.1 механизм хранения MEMORY реализовывал только
хешированные индексы. Начиная с версии MySQL 4.1, хешированные индексы
используются по умолчанию, однако с помощью конструкции USING вы можете
явно указать, что индексом таблицы MEMORY должен быть HASH или BTREE:
CREATE TABLE lookup
(id INT, INDEX USING HASH (id))
ENGINE = MEMORY;
CREATE TABLE lookup
(id INT, INDEX USING BTREE (id))
ENGINE = MEMORY;
514 Глава 8. Механизмы хранения и типы таблиц в MySQL

Общие характеристики индексов на основе В-деревьев и хеширования, описаны в


разделе 6.4.5.
• В таблице MEMORY могут содержаться неуникальные ключи (что не является нор-
мой для хешированных таблиц).
• Если в таблице MEMORY с высокой степенью дублирования ключей (несколько ста-
тей индекса с одним и тем же значением) имеется хешированный индекс, то про-
цессы обновления таблицы, влияющие на значения ключей, и удаления будут
происходить очень медленно. Степень замедления работы пропорциональна сте-
пени дублирования (или обратно пропорциональна количеству индексов). Для
решения этой проблемы можно использовать индекс BTREE.
• Таблицы MEMORY используют формат с фиксированной длиной записи.
• Таблицы MEMORY не поддерживают столбцы BLOB или TEXT.
• Таблицы MEMORY не поддерживают столбцы AUTO_INCREMENT.
• До выхода версии MySQL 4.0.2 таблицы MEMORY не поддерживали индексы в
столбцах, которые содержали значения NULL.
• Таблицы MEMORY используются совместно всеми клиентами (подобно любой дру-
гой таблице).
• Свойство таблицы MEMORY, вследствие которого содержимое таблицы хранится в
памяти, позволяет внутренним таблицам, которые сервер создает оперативно в
процессе обработки запросов, совместно работать с ней. Однако внутренние таб-
лицы обладают свойством, благодаря которому сервер автоматически преобразо-
вывает их в "таблицы на диске" (on-disk table), если их размер становится черес-
чур большим. Предельно допустимый размер определяется значением системной
переменной tmp_table_size.
Таблицы MEMORY не преобразовываются в дисковые таблицы. Чтобы обеспечить
защиту от случайных неквалифицированных действий, можно присвоить систем-
ной переменной tmp_table_size значение, соответствующее максимальному раз-
меру таблиц MEMORY. Для индивидуальных таблиц можно также задать опция
MAX_ROWS В операторе CREATE TABLE.
• Чтобы поддерживать все одновременно используемые таблицы MEMORY, серверу
необходима дополнительная память достаточного объема.
• Чтобы освободить память, занимаемую таблицей MEMORY, содержимое которой
вам больше не нужно, потребуется выполнить оператор DELETE или
TRUNCATE_TABLE, или же удалить таблицу с помощью DROP TABLE.
• Если необходимо заполнить таблицу MEMORY данными во время запуска сервера
MySQL, то для этого можно использовать опцию — i n i t - f i l e . Например, в файл
для загрузки таблицы из постоянного источника данных можно поместить опера-
тор INSERT INTO. . .SELECT ИЛИ LOAD DATA INFILE. См. раздел 4.2.1.
• Если использовать репликацию, то таблицы MEMORY, хранящиеся на главном сер-
вере, будут становиться пустыми после его выключения и перезапуска. Однако
подчиненному серверу не известно, являются ли эти таблицы пустыми, поэтому
при попытке извлечь из них данные вам будет возвращено устаревшее содержи-
мое. Начиная с версии MySQL 4.0.18, когда таблица MEMORY использовалась на
8.4. Механизм хранения данных BDB (BerkleyDB) 515

главном сервере впервые с момента его запуска, оператор DELETE FROM регистри-
ровался в бинарном журнале главного сервера автоматически, синхронизируя
подчиненный и главный серверы. Обратите внимание на то, что даже с учетом
упомянутой стратегии подчиненный сервер все равно будет хранить устаревшие
данные в таблице в промежутке времени между перезапуском главного сервера и
первым его обращением к таблице. Однако если для заполнения таблицы MEMORY
во время запуска главного сервера указать опцию — i n i t - f i l e , интервал простоя
будет равен нулю.
• Объем памяти, необходимый для одной строки в таблице MEMORY, можно вычис-
лить следующим образом:
SUM_OVER_ALL_KEYS(max_length_of_key + sizeof(char*) * 2)
+ ALIGN(length_of_row+l, sizeof(char*))
ALIGN () соответствует коэффициенту округления, благодаря которому длина
строки будет кратна размеру указателя char. Величина sizeof (char*) равна 4 на
32-разрядных компьютерах и 8 на 64-разрядных.

8.4. Механизм хранения данных BDB


(BerkleyDB)
Компания Sleepycat Software разработала для MySQL механизм хранения Berkley DB,
который обычно называют BDB для краткости. Поддержка таблиц этого типа включена в
исходный дистрибутив MySQL, начиная с версии 3.23.34а, а также присутсвует в бинар-
ных дистрибутивах MySQl-Max.
Таблицы BDB имеют больше всего шансов оставаться целыми после сбоев. Над этими
таблицами могут быть выполнены операции COMMIT и ROLLBACK для транзакций. Дистри-
бутив MySQL поставляется вместе с дистрибутивом BDB, в котором было сделано не-
сколько исправлений, позволивших устранить некоторые проблемы при работе с
MySQL. Использование версии BDB без исправлений в MySQL невозможно.
Разработчики компании MySQL AB работают в тесном сотрудничестве с компанией
Sleepycat, что дает возможность постоянно поддерживать на высоком уровне качество
интерфейса MySQL/BDB. (Несмотря на надежность и тщательную проверку Berkley DB,
интерфейс MySQL по-прежнему не отвечает самым высоким требованиям, поэтому ра-
боты над его улучшением и оптимизацией продолжаются.)
Что касается поддержки таблиц BDB, то мы оказываем всяческую помощь нашим
пользователям в выявлении проблем и создании воспроизводимых тестовых случаев.
Каждый тестовый случай передается в Sleepycat, которая, в свою очередь, помогает вы-
являть и исправлять ошибки. Поскольку эта операция проходит в два этапа, то на реше-
ние проблем с таблицами BDB может быть потрачено больше времени, чем на решение
похожих проблем с другими таблицами. Однако мы считаем, что эта процедура не
должна вызывать каких-либо серьезных затруднений, поскольку код Berkley DB исполь-
зуется во многих приложениях, отличных от MySQL. См. раздел 1.4.1.
Сведения о деятельности компании Berkley DB можно получить на сайте Sleepycat по
адресу http://www.sleepycat.com.
516 Глава 8. Механизмы хранения и типы таблиц в MySQL

8.4.1. Операционные системы, поддерживающие BDB


В настоящее время механизм хранения BDB может работать под управлением сле-
дующих операционных систем:
• Linux 2.x Intel
• Sun Solaris (SPARC и х86)
• FreeBSD4.x/5.x(x86, sparc64)
• IBM AIX 4.3.x
• SCO OpenServer
• SCO UnixWare 7.1.x
Под управлением перечисленных ниже операционных систем механизм хранения BDB
не работает:
• Linux 2.x Alpha
• Linux 2.x AMD64
• Linux 2.x IA-64
• Linux 2.x s390
• Mac OS X
]*; На зметку!
f*
%\ Представленные списки не являются полными. Мы обновим их, как только получим более де-
У'. тальную информацию.
В случае выполнения сборки MySQL на основе исходного кода с поддержкой таблиц
BDB, если при запуске mysqld возникает приведенная ниже ошибка, это означает, что ме-
ханизм BDB существующей архитектурой не поддерживается:
bdb: architecture lacks fast mutexes: applications cannot be threaded
Can't i n i t databases
bdb: в архитектуре отсутствуют быстрые семафоры: приложения не могут быть
разбиты на потоки
Невозможно инициализировать базы данных
В этом случае потребуется пересобрать MySQL без поддержки таблиц BDB или запус-
тить сервер с опцией —skip-bdb.

8.4.2. Установка BDB


Если вы располагаете загруженной бинарной версией MySQL, которая включает
поддержку Berkley DB, достаточно будет выполнить обычные инструкции по установке
бинарного дистрибутива. (Дистрибутивы MySQl-Max включают поддержку BDB.)
Если вы собираете MySQL на основе исходного кода, можно включить поддержку
BDB, выполнив команду configure с опцией —with-berkley-db в дополнение к осталь-
ным обычно используемым опциям. Загрузите дистрибутив MySQl 3.23.34 или более
новой версии, перейдите в каталог верхнего уровня и выполните следующую команду:
shell> ./configure —with-berkeley-db [другие-опции]
Более подробные сведения можно найти в разделах 2.2.5, 4.1.2 и 2.3.
8.4. Механизм хранения данных BDB (BerkleyDB) 517

8.4.3. Опции запуска BDB


Для изменения поведения механизма хранения BDB служат следующие опции коман-
ды mysqld:
• --bdb-home=путь. Базовый каталог для таблиц BDB. Это должен быть тот же ката-
лог, что и каталог для —datadir.
• —bdb-lock-detect=Mero4. Способ обнаружения блокировки BDB. Опция может
принимать одно из значений DEFAULT, OLDEST, RANDOM или YOUNGEST.
• —bdb-logdir=путь. Каталог журнальных файлов BDB.
• —bdb-no-recover. He запускать Berkley DB в режиме восстановления данных.
• —bdb-no-sync. He сбрасывать синхронно на диск журналы BDB.
• —bdb-shared-data. Запустить Berkley DB в режиме параллельной обработки. (Не
используйте DBPRIVATE при инициализации Berkley DB.)
• —bdb-tmpdir=nyrb. Каталог временных файлов BDB.
• —skip-bdb. He использовать таблицы BDB.
См. раздел 4.2.1.
Следующая системная переменная влияет на поведение таблиц BDB:
• bdbmaxlock. Максимальное количество возможных блокировок, которые могут
оставаться активными в таблице BDB.
См. раздел 4.2.3.
Если указать опцию --skip-bdb, MySQL не будет инициализировать библиотеку
Berkley DB, что позволит сэкономить довольно-таки большой объем памяти. Однако в
этом случае вы не сможете пользоваться таблицами BDB. Если вы попытаетесь создать
таблицу BDB, MySQL создаст вместо нее таблицу My ISAM.
Обычно, если вы не намерены использовать таблицы BDB, следует запускать mysqld
без опции --bdb-no-recover. Однако если вы попытаетесь запустить mysqld при повре-
жденных журнальных файлах BDB, могут возникнуть проблемы. См. раздел 2.4.4.
С помощью переменной bdb_max_lock можно задать максимальное количество бло-
кировок, которые могут быть установлены на таблицу BDB. По умолчанию их количество
составляет 10 000. Это значение следует увеличить, если при выполнении продолжи-
тельных транзакций, а также когда mysqld для выполнения запроса необходимо прове-
рить множество строк, встречаются ошибки следующего рода:
bdb: Lock table is out of available locks
Got error 12 from . . .
Можно также изменить переменные binlog_cache_size и max_binlog_cache_size,
если будут применяться продолжительные транзакции с множеством операторов. См.
раздел 4.8.4.

8.4.4. Характеристики таблиц BDB


Каждая таблица BDB хранится на диске в виде двух файлов. Имя файла начинается с
имени таблицы, а расширение указывает на тип файла. В файле . f rm хранится определе-
ние таблицы, а в файле . db - данные таблицы и индексы.
518 Глава 8. Механизмы хранения и типы таблиц в MySQL

Чтобы указать явно, что вы хотите работать с таблицей BDB, воспользуйтесь таблич-
ной опцией ENGINE или TYPE:
CREATE TABLE t (i INT) ENGINE = BDB;
CREATE TABLE t (i INT) TYPE = BDB;
В опциях ENGINE и TYPE BerkleyDB является синонимом BDB.
Механизм хранения BDB работает с транзакционными таблицами. Варианты исполь-
зования этих таблиц зависят от режима автоматической фиксации:
• Если вы работаете с включенной автоматической фиксацией (она включена по
умолчанию), изменения в таблицах BDB будут незамедлительно фиксироваться, и
не могут быть возвращены.
• Если вы работаете с отключенной автоматической фиксацией, изменения не будут
фиксироваться до тех пор, пока вы не выполните команду COMMIT. Вместо фикса-
ции можно выполнить команду ROLLBACK, чтобы отменить внесенные изменения.
Можно запустить транзакцию с помощью оператора BEGIN WORK, чтобы приоста-
новить автоматическую фиксацию, или SET AUTOCOMMIT=0, чтобы запретить ее яв-
ным образом.
Ниже представлены характеристики механизма хранения BDB.
• Таблицы BDB могут иметь 31 индекс в таблице, 16 столбцов в индексе, а макси-
мальный размер ключа может составлять 1024 байт (до выхода версии MySQL 4.0
этот размер составлял 500 байт).
• Чтобы можно было уникальным образом идентифицировать каждую строку, в
каждой таблице BDB должен присутствовать первичный ключ (PRIMARY KEY). Если
вы сами не создадите его явным образом, MySQL создаст и будет поддерживать
для вас скрытый первичный ключ. Скрытый ключ имеет длину 5 байт, и будет
увеличиваться с каждой попыткой вставки данных.
• Первичный ключ (PRIMARY KEY) будет работать гораздо быстрее, чем любой дру-
гой индекс, поскольку он хранится вместе с данными строки. Остальные индексы
хранятся как данные ключа плюс первичный ключ, поэтому лучше всего работать
с наименее коротким первичным ключом, что позволит увеличить скорость рабо-
ты и сэкономить пространство на диске.
Это же касается и таблиц InnoDB, в которых короткие первичные ключи позволя-
ют экономить пространство диска не только в первичном, но и во вторичных ин-
дексах.
• Если все столбцы, к которым вы производите обращение в таблице BDB, являются
частью одного индекса или одного первичного ключа, MySQL может выполнить
запрос, не обращаясь к самой строке. В таблице MylSAM это можно сделать только
в том случае, если ее столбцы являются частью одного индекса.
• Последовательное сканирование выполняется медленнее, чем в таблицах My ISAM,
поскольку данные в таблицах BDB хранятся в В-деревьях, а не в отдельном файле
данных.
• Значения ключей не сжимаются в префиксах или суффиксах, как в таблицах
My ISAM. Другими словами, информация о ключе в таблицах BDB занимает чуть
больше места, чем в таблицах My ISAM.
8.4. Механизм хранения данных BDB (BerkleyDB) 519

• В таблице BDB имеются промежутки, в которые можно вставлять новые строки в


середине индексного дерева. Как следствие, размер таблиц BDB превышает размер
таблиц My IS AM.
• Поскольку в таблицах BDB не поддерживаются счетчики строк, оператор SELECT
COUNT (*) FROM имя_таблицы выполняется медленнее.
• Оптимизатору необходимо знать приблизительное количество строк в таблице.
MySQL определяет это значение, подсчитывая вставки и поддерживая его в от-
дельном сегменте в каждой таблице BDB. Если было выполнено всего несколько
операторов DELETE или ROLLBACK, этого значения должно быть достаточно для оп-
тимизатора MySQL. Однако MySQL сохраняет его только при закрытии, поэтому
данное значение может оказаться ошибочным, если сервер вдруг прекратит свою
работу. Следует иметь в виду, что если это значение не будет точным, ошибки все
равно не произойдет. Значение счетчика строк можно будет обновить с помощью
ANALYZE TABLE ИЛИ OPTIMIZE TABLE.

• Внутренняя блокировка в таблицах BDB выполняется на уровне страниц.


• Оператор LOCK TABLES работает с таблицами BDB точно так же, как и с другими
таблицами. Если LOCK TABLES не используется, MySQL устанавливает для данной
таблицы внутреннюю блокировку множественной записи (благодаря которой не
будут блокироваться другие потоки, осуществляющие запись). В результате, если
другой поток установит блокировку таблицы, она заблокируется корректно.
• Чтобы иметь возможность выполнять откаты транзакций, механизм хранения BDB
поддерживает журнальные файлы. Для достижения максимальной производи-
тельности используется опция —bdb-logdir. В этой опции можно указать другой
диск, на котором будут размещены журналы BDB (а не диск, на котором размеще-
на сама база данных).
• Когда начинается новый файл журнала BDB, MySQL выполняет контрольную про-
верку и удаляет любые журналы, не используемые для текущих транзакций. Вы-
полнить контрольную проверку таблиц BDB в любое время можно с помощью опе-
ратора FLUSH LOGS.
Чтобы выполнить восстановление после сбоя, необходимо использовать резерв-
ные копии таблиц и бинарный журнал MySQL. См. раздел 4.6.1.
р Внимание!
!| Если вы удалите старые журнальные файлы, которые все еще используются, BDB не сможет вы-
ff полнить восстановление, и в случае сбоя вы можете потерять данные.

• Приложения всегда должны быть готовы к обработке ситуаций, при которых вся-
кое изменение в таблице BDB может вызвать автоматический откат, а всякое чте-
ние может привести к взаимной блокировке.
• Если таблица BDB заполняет все пространство на диске, выводится сообщение об
ошибке (возможно, ошибка 28) и выполняется откат транзакции. В этом заключа-
ется отличие этих таблиц от таблиц My ISAM и ISAM, для которых mysqld будет
ожидать появления достаточного объема дискового пространства, прежде чем
продолжить работу.
520 Глава 8. Механизмы хранения и типы таблиц в MySQL

8.4.5. Что должно быть исправлено в механизме


хранения BDB
• Процесс одновременного открытия нескольких таблиц BDB происходит слишком
долго. Для работы с таблицами BDB не нужно иметь слишком большой кэш таблицы
(например, больше 256 Кбайт), и для клиента mysqld необходимо указывать опцию
--no-auto-rehash. Мы планируем частично исправить это в версии MySQL 4.O.
• SHOW TABLE STATUS до сих пор не предоставляет достаточный объем информации
по таблицам BDB.
• Необходимо оптимизировать производительность.
• При сканировании таблиц необходимо отказаться от использования блокировок
страниц.

8.4.6. Ограничения при использовании таблиц BDB


Ниже приведен список ограничений, с которыми необходимо ознакомиться перед
тем, как приступить к использованию таблиц BDB.
• В файле .db содержится информация о том, где будет храниться создаваемый
файл. Это необходимо для того, чтобы можно было обнаружить блокировки в
многопользовательской среде, в которой поддерживаются символические ссылки.
По причине этого файлы таблиц BDB нельзя перемещать из одного каталога базы
данных в другой.
• При создании резервных копий таблиц BDB вы должны либо использовать
mysqldump, либо создавать резервную копию с файлами для каждой таблицы BDB
(файлы .frm и .db) и журнальными файлами BDB. Механизм хранения BDB хранит
незавершенные транзакции в своих журнальных файлах в каталоге данных; фай-
лам присваиваются имена в виде log.XXXXXXXXXX (десять цифр).
• Если столбец, в котором могут храниться значения NULL, имеет уникальный ин-
декс, то в нем можно хранить только одно значение NULL. Это одно из отличий BDB
от остальных механизмов хранения.

8.4.7. Ошибки, которые могут возникать при


использовании таблиц BDB
• Если при запуске mysqld возникает следующая ошибка, это означает, что новая
версия BDB не поддерживает старый формат журнального файла:
bdb: Ignoring log file: .../log.XXXXXXXXXX:
unsupported log version #
В этом случае потребуется удалить журналы BDB из каталога данных (файлы с
именами в формате log.XXXXXXXXXX) и перезапустить mysqld. Мы рекомендуем
также использовать mysqldump —opt, чтобы сохранить таблицы BDB, удалить ста-
рые файлы таблиц и восстановить данные из сохраненного файла.
• Если при отключенном режиме автоматической фиксации удалить таблицу BDB,
которая ссылается на другую транзакцию, в журнале ошибок MySQL может поя-
виться следующие сообщения об ошибках:
8.5. Механизм хранения ISAM 521

001119 23:43:56 bdb: Missing log f i l e i d entry


001119 23:43:56 bdb: txn_abort: Log undo failed for LSN:
1 3644744: Invalid
Эти ошибки не являются фатальными, однако до тех пор, пока эта проблема не
будет решена, мы рекомендуем не удалять таблицы BDB при включенном режиме
автоматической фиксации. (Эта проблема является достаточно сложной.)

8.5. Механизм хранения ISAM


Самым первым механизмом хранения в MySQL был ISAM. До выхода версии MySQL
3.23, в которой был представлен механизм MylSAM, это был единственный доступный
механизм хранения. В настоящее время механизм ISAM используется очень редко. В вер-
сии MySQL 4.1 он включен в исходный код, однако не входит в состав бинарных дист-
рибутивов. Из версии MySQL 5.0 он будет полностью изъят. Встроенные версии сервера
MySQL по умолчанию не поддерживают таблицы ISAM.
Поскольку механизм ISAM используется крайне редко, а также по причине явного
превосходства механизма My ISAM, мы рекомендуем преобразовать существующие табли-
цы ISAM в таблицы My ISAM с помощью оператора ALTER TABLE:
mysql> ALTER TABLE имя_таблицы TYPE = MYISAM;
Дополнительную информацию по MylSAM можно найти в разделе 8.1.
Каждая таблица ISAM хранится на диске в виде трех файлов. Имя файла начинается с
имени таблицы, а расширение указывает на тип файла. В файле . f rm содержится описа-
ние таблицы, файл данных имеет расширение .ISD, а индексный файл - расширение
.ISM.
В механизме ISAM применяются индексы в виде В-деревьев.
Проверка или восстановление таблиц ISAM осуществляется с помощью утилиты
isamchk. См. раздел 4.6.2.7.
Таблица ISAM обладает следующими свойствами:
• Сжатые ключи фиксированной длины.
• Фиксированная и динамическая длина записи.
• 16 индексов в таблице с 16 частями в каждом ключе.
• Максимальная длина ключа составляет 256 байт (по умолчанию).
• Значения данных хранятся в машинном формате; это повышает скорость работы с
данными, хотя и возникает зависимость от компьютера и операционной системы.
Многие свойства таблиц MylSAM характерны и для таблиц ISAM. Однако между ними
существует немало отличий, среди которых следует упомянуть такие:
• Таблицы ISAM нельзя переносить между операционными системами и платформа-
ми в двоичном виде.
• Не допускается работа с таблицами, размер которых превышает 4 Гбайт.
• В строках поддерживается только сжатие префикса.
• Ограничения по маленьким ключам (более строгие).
• Динамические таблицы становятся более фрагментированными.
• Не поддерживаются таблицы MERGE.
522 Глава 8. Механизмы хранения и типы таблиц в MySQL

• Проверка и восстановление поврежденных таблиц осуществляется с помощью


утилиты isamchk, а не myisamchk.
• Сжатие таблиц производится посредством утилиты pack_isam, а не myisampack.
• Нельзя использовать операторы создания резервных копий BACKUP TABLE или
RESTORE TABLE.
• Нельзя использовать операторы обслуживания таблиц CHECK TABLE, REPAIR TABLE,
OPTIMIZE TABLE ИЛИ ANALYZE TABLE.

• He поддерживается полнотекстовый поиск и пространственные типы данных.


• Таблицы не поддерживают множественные символьные наборы.
• Индексы не могут присваиваться кэшам определенных ключей.
9
Механизм хранения
InnoDB

9.1. Обзор InnoDB


InnoDB является транзакционным (совместимым с ACID) механизмом хранения
MySQL, который позволяет фиксировать транзакции, выполнять их откат, а также вос-
станавливать данные после сбоя. Для таблиц InnoDB доступна блокировка на уровне
строки и используется метод согласованного чтения без блокировок в операторах SELECT
(так же, как в Oracle). Эти функции улучшают параллелизм и повышают производи-
тельность в многопользовательском режиме. Для InnoDB не требуется расширение бло-
кировки, поскольку блокировки на уровне строки в этих таблицах занимают очень мало
места. Для таблиц InnoDB поддерживаются ограничения FOREIGN KEY. В запросах SQL
вы можете свободно сочетать таблицы типа InnoDB с таблицами другого типа MySQL,
даже в одном и том же запросе.
Механизм хранения данных InnoDB разрабатывалась с той целью, чтобы обеспечить
максимальную производительность при обработке больших объемов данных. По эффек-
тивности использования процессора ей нет равных среди других моделей реляционных
баз данных с сохранением на диске.
Будучи полностью интегрированным в сервер MySQL, механизм InnoDB поддержи-
вает свой собственный буферный пул для кэширования данных и индексов в основной
памяти. InnoDB хранит свои таблицы и индексы в пространстве памяти, которое может
состоять из нескольких файлов (или низкоуровневых разделов диска). В этом заключа-
ется отличие InnoDB от, например, механизма My ISAM, в котором каждая таблица хранит-
ся в отдельном файле. Таблицы InnoDB могут иметь любой размер даже в тех операци-
онных системах, в которых он ограничен 2 Гбайт.
Начиная с версии MySQL 4.0, InnoDB входит в состав бинарного дистрибутива. До-
полнительную информацию о поддержке таблиц InnoDB в MySQL 3.23 можно найти в
разделе 9.3.
Таблицы InnoDB применяются в многочисленных крупных сайтах, взаимодействую-
щих с базами данных и, соответственно, требующих высокой производительности. Так,
например, механизм InnoDB используется на популярном сайте новостей Slashdot.org.
Формат InnoDB применяется для хранения более 1 Тбайт данных в компании Mytrix, Inc.,
а еще на одном сайте механизм InnoDB позволяет справляться с нагрузкой, исчисляемой
в среднем 800 вставками/обновлениями в секунду.
524 Глава 9. Механизм хранения InnoDB

InnoDB распространяется на условиях общедоступной лицензии GNU GPL версии 2


(с июня 1991 года). Если вы занимаетесь распространением MySQL/InnoDB и ваше при-
ложение не отвечает требованиям лицензионного соглашения GPL, вам следует приоб-
рести коммерческую лицензию MySQL Pro на сайте:
https://order.mysql.com/?sub=pg&pg_no=l

9.2. Контактная информация,


касающаяся InnoDB
Ниже представлена контактная информация Innobase Oy, производителя механизма
хранения InnoDB:
Web-сайт: http://www.InnoDB.com/
Электронная почта: [email protected]
Телефон: +358-9-6969 3250 (офис)
+358-40-5617367 (мобильный)
Innobase Oy Inc.
World Trade Center Helsinki
Aleksanterinkatu 17
P.O. Box 800
00101 Helsinki
Finland

9.3. Таблицы InnoDB в MySQL 3.23


Начиная с версии MySQL 4.0, таблицы InnoDB доступны по умолчанию, поэтому
представленная ниже информация касается только MySQL 3.23.
Начиная с версии MySQL 3.23.34а, таблицы InnoDB входят в состав исходного дист-
рибутива MySQL и задействованы в бинарных файлах MySQL-Max серии 3.23. Для
Windows бинарные файлы MySQL-Max включены в стандартный дистрибутив.
Если вы загрузили бинарную версию MySQL, которая включает поддержку InnoDB,
вам будет достаточно выполнить инструкции руководства по установке бинарной вер-
сии MySQL. Если у вас уже установлена MySQL 3.23, тогда самый простой способ уста-
новки MySQL-Max будет заключаться лишь в том, чтобы заменить исполняемый файл
mysqld соответствующим файлом из дистрибутива MySQL-Max. MySQL и MySQL-Max
отличаются только исполняемыми файлами сервера. См. разделы 2.2.5 и 4.1.2.
Чтобы скомпилировать MySQL с поддержкой InnoDB, загрузите версию MySQL
3.23.34а или более новую версию с сайта http://www.mysql.com/ и сконфигурируйте
MySQL с опцией —with-InnoDB. См. раздел 2.3.
Чтобы использовать таблицы InnoDB в MySQL 3.23, необходимо указать конфигура-
ционные параметры InnoDB в разделе [mysqld] файла my.cnf. В Windows для этого ис-
пользуется файл my.ini. Если не сконфигурировать InnoDB в файле опций, механизм
InnoDB запустить не удастся. (Начиная с версии MySQL 4.0, если вы не указываете свои
параметры, в InnoDB используются параметры, принятые по умолчанию. Чтобы достичь
наиболее высокой производительности, рекомендуется выбирать значения параметров в
соответствии с требованиями вашей системы; об этом говорится в разделе 9.4.)
9.4. Конфигурация InnoDB 525

Минимальным требованием конфигурирования файлов данных InnoDB в версии


MySQL 3.23 является установка значения innodb_data_file_path. Например, чтобы
сконфигурировать InnoDB для использования одного автоматически расширяющегося
файла данных размером 10 Мбайт, в раздел [mysqld] файла опций необходимо помес-
тить следующие строки:
[mysqld]
innodb_data_file_path=ibdata:ЮМ:autoextend
По умолчанию InnoDB создает файл ibdatal в каталоге данных MySQL. Для явного
указания местоположения файла служит параметр innodb_data_home_dir. См. раздел 9.4.

9.4. Конфигурация InnoDB


Вопросам использования таблиц InnoDB в MySQL 3.23 посвящен раздел 9.3.
Начиная с версии MySQL 4.0, InnoDB используется по умолчанию. Если вас не инте-
ресуют таблицы InnoDB, в файле опций MySQL добавьте опцию skip-InnoDB.
InnoDB управляет двумя дисковыми ресурсами - файлами данных табличного про-
странства и файлами журналов.
Если вы не укажете параметры конфигурации InnoDB, в MySQL 4.0 и выше будет
создан автоматически расширяющийся файл размером 10 Мбайт с именем ibdatal и два
файла журналов размером по 5 Мбайт каждый с именами ib_logfileO и ib_logfilel в
каталоге данных MySQL (в MySQL 4.0.0 и 4.0.1 размер файла данных составляет
64 Мбайт, причем он не является автоматически расширяющимся). В MySQL 3.23
InnoDB без параметров конфигурации запускать нельзя.
На заметку!
Чтобы достичь высокой производительности, необходимо явным образом задать параметры
InnoDB, представленные в следующих примерах. Естественно, вы будете иметь дело с собст-
венными значениями параметров, которые соответствуют существующему оборудованию и
удовлетворяют конкретным требованиям.

Для настройки файлов табличного пространства InnoDB применяется опция


innodb_data_file_path в разделе [mysqld] файла my.cnf. В среде Windows используется
файл my.ini. В качестве значения innodb_data_file_path необходимо указать перечень
спецификаций одного или нескольких файлов данных. Если вы перечисляете несколько
файлов данных, для их разделения следует использовать точку с запятой:
innodb_data_file_path=
спецификация_файла_данных1 [; спецификация_файла_данных2) . . .
Далее показан пример параметра настройки, явным образом создающего табличное
пространство, которое имеет те же характеристики, что и характеристики, используемые
по умолчанию в MySQL 4.0:
[mysqld]
innodb_data_file_path=ibdatal:ЮМ:autoextend
В данном примере указываются параметры одиночного автоматически расширяюще-
гося файла размером 10 Мбайт с именем ibdatal. Размещение этого файла не указано,
поэтому по умолчанию он попадет в каталог данных MySQL.
Размеры файла указываются с помощью суффиксов М и G, соответственно для Мбайт и
Гбайт.
526 Глава 9. Механизм хранения InnoDB

Табличное пространство, содержащее файл данных ibdatal с фиксированным разме-


ром 50 Мбайт и автоматически расширяющийся файл ibdata2 размером 50 Мбайт в ка-
талоге данных можно сконфигурировать следующим образом:
[mysqld]
innodb_data_file_path=ibdatal:50М;ibdata2:50M:autoextend
Полный синтаксис спецификации файла данных включает имя файла, его размер и
несколько необязательных атрибутов:
имя файла:размер_файла (: autoextend (: max:максимальный_размер_файла))
Атрибут autoextend, а также последующие атрибуты, могут использоваться только
для последнего файла данных в строке innodb_data_file_path. Атрибут autoextend
доступен, начиная с версий MySQL 3.23.50 и 4.0.2.
Если атрибут autoextend задать для последнего файла данных, то InnoDB увеличит
размер файла данных после того, как он займет все свободное место в табличной облас-
ти. С каждым новым увеличением файл будет получать дополнительные 8 Мбайт.
Если текущий диск окажется заполненным, можно будет добавить еще один файл
данных, но уже на другом диске. Инструкции по перестройке существующего таблично-
го пространства представлены в разделе 9.8.
Механизму InnoDB не известно о максимально возможном размере файла, поэтому
следует быть внимательным при работе с файловыми системами, в которых размер фай-
ла ограничен 2 Гбайт. Чтобы задать максимальный размер для автоматически расши-
ряющегося файла данных, используйте атрибут max. Ниже показан пример того, как
можно увеличить предельно допустимый размер файла ibdatal до 500 Мбайт:
[mysqld]
innodb_data_file_path=ibdatal:10M:autoextend:max:500M
По умолчанию InnoDB создает файлы табличного пространства в каталоге данных
MySQL. Чтобы явным образом указать местоположение файлов, воспользуйтесь опцией
innodb_data_home_dir. Например, чтобы использовать два файла с именами ibdatal и
ibdata2 в каталоге /ibdata, необходимо сконфигурировать InnoDB следующим образом:
[mysqld]
innodb_data_home_dir=/ibdata
innodb_data_file_path=/ibdatal:50M;ibdata2:50M:autoextend
II На заметку!
ы InnoDB не создает каталоги, поэтому перед запуском сервера потребуется проверить, существу-
Ь ет ли каталог / i b d a t a . Это справедливо также и для конфигурируемых вами каталогов жур-
|; нальных файлов. Для создания каталога выполните команду mkdir в Unix или DOS.

InnoDB формирует путь к каталогу для каждого файла данных, присоединяя


innodb_data_home_dir к имени файла данных, при необходимости добавляя прямую или
обратную косую черту. Если параметр innodb_data_home_dir вообще не указан в файле
my.cnf, то по умолчанию будет использоваться каталог "точка" ./, который обозначает
каталог данных MySQL.
Если определить параметр innodb_data_home_dir как пустую строку, тогда мож-
но будет указать абсолютные пути к файлам данных, перечисленных в списке
innodb_data_f ilejpath. Следующий пример аналогичен предыдущему:
9.4. Конфигурация InnoDB 527

[mysqld]
innodb_data_home_dir=innodb_data_file_path=
ibdata/ibdatal:50M/ibdata/ibdata2:50M:autoextend
Простой пример файла my.cnf
Предположим, что у вас есть компьютер с ОЗУ объемом 128 Мбайт и одним жестким
диском. В предложенном ниже примере показаны возможные конфигурационные пара-
метры в файле my.cnf или my.ini для InnoDB. Предполагается, что у вас установлена
версия MySQL-Max 3.23.50 и выше или MySQL 4.0.2 и выше, поскольку в этом примере
используется параметр autoextend.
Этот пример будет интересен тем пользователям Unix и Windows, которые не хо-
тят размещать свои файлы данных и файлы журналов на различных дисках. Здесь
создается автоматически расширяющийся файл ibdatal и два файла журналов
ib_logfileO и ib_logfilel в каталоге данных MySQL. Кроме этого, в этом каталоге
находится небольшой автоматически создаваемый InnoDB архивный файл журнала
ib_arch_log_0000000000:
[mysqld]
# Сюда можно добавить другие параметры сервера MySQL
# ...
# Файлы данных должны иметь достаточный размер для
# для хранения ваших данных и индексов.
# Убедитесь что у вас достаточно
# свободного места на диске.
innodb_data_file_path = ibdatal:10M:autoextend
#
# Размер буферного пула должен составлять
# от 50 до 80% памяти вашего компьютера,
set-variable = innodb_buffer_pool_size=70M
set-variable = innodb_additional_mem_pool_size=10M
#
# Размер журнального файла должен составлять
# около 25% от размера буферного пула,
set-variable = innodb_log_file_size=20M
set-variable = innodb_log_buffer_size=8M
#
innodb_flush_log_at_trx_commit=l
Убедитесь в том, что сервер MySQL имеет права на создание файлов в каталоге дан-
ных. Как правило, сервер должен иметь права доступа к любому каталогу, в котором ему
необходимо создать файлы данных и файлы журналов.
Не забывайте, что в некоторых файловых системах размер файла не должен превы-
шать 2 Гбайт. Общий размер файлов журналов должен быть менее 4 Гбайт, а общий
размер файлов данных - как минимум 10 Мбайт.
Когда вы впервые создаете табличное пространство InnoDB, лучше всего запустить
сервер MySQL из командной строки. Тогда на экран будет выводиться информация о
создании базы данных, и вы сможете следить за происходящими событиями. Например,
если в системе Windows mysqld-max расположен в каталоге C:\mysql\bin, его можно
запустить следующим образом:
С:\> С:\mysql\bin\mysqld-max —console
528 Глава 9. Механизм хранения InnoDB

Если вы не направляете вывод сервера на экран, просмотрите журнал регистрации


ошибок сервера, чтобы узнать, какую информацию выводит InnoDB во время запуска.
В разделе 9.6 можно найти пример информации, выводимой InnoDB.
Где указывать параметры в Windows?
Для Windows существуют следующие правила:
• Должен быть создан только один файл - my. cnf или ту. ini.
• Файл ту. cnf должен находиться в корневом каталоге диска С:.
• Файл my.ini должен находиться в каталоге WINDIR; например, в C:\WINDOWS или
C:\WINNT. Для просмотра значения WINDIR воспользуйтесь командой SET в ко-
мандной строке:
С:\> SET WINDIR
Windir=C:\WINNT
• Если в компьютере используется начальный загрузчик, в котором диск С: не яв-
ляется загрузочным, необходимо использовать файл my. ini.
Где указываются параметры в Unix?
В Unix mysqld считывает параметры из следующих файлов, если они существуют, в
таком порядке:
• /etc/my, cnf. Общие параметры.
• КАТАЛОГ_ДАННЫХ/my.cnf. Параметры сервера.
• defaults-extra-file. Файл, указанный в параметре —defaults-extra-file.
• ~/.my. cnf. Параметры пользователя.
КАТАЛОГ_ДАННЫХ обозначает каталог данных MySQL, который был определен в каче-
стве опции для configure при компиляции mysqld (обычно /usr/local/mysql/data для
установки исполняемых файлов или /usr/local/var для установки исходного кода).
Если вы хотите убедиться в том, что mysqld считывает параметры только из опреде-
ленного файла, то при запуске сервера можно указать --defaults-option как первую
опцию в командной строке:
mysqld —defaults-file=Bam_nyTb_K_my_cnf
Расширенный пример файла my.cnf
Предположим, что у вас есть компьютер, работающий под управлением Linux, с ОЗУ
2 Гбайт и тремя жесткими дисками по 60 Гбайт (с путями к каталогам /, /dr2 и /dr3). В
приведенном ниже примере показаны вероятные параметры конфигурации в файле
my. cnf для InnoDB.
[mysqld]
# Здесь вы можете задать другие параметры сервера MySQL
# ...
innodb_data_home_dir =
#
# Файлы данных должны иметь достаточный размер для
# хранения ваших данных и индексов.
# Введите полное значение innodb__data_file_path в одной строке.
innodb_data_file_path=/ibdata/ibdatal:2000M;
9.4. Конфигурация InnoDB 529

/dr2/ibdata/ibdata2:2000M:autoextend
#
# Размер буферного пула должен составлять
# от 50 до 80% памяти вашего компьютера;
# пользователям Linux x86 следует убедиться, что
# общая занимаемая память не превышает 2 Гб.
set-variable = innodb_buffer_pool_size=lG
set-variable = innodb_additional_mem_pool_size=20M
innodb_logjgroup_home_dir = /dr3/iblogs
#
# innodb_log_arch_dir должен быть таким же,
# как и innodb_log_group_home_dir
# (начиная с версии 4.0.6, этот параметр можно опустить).
innodb_log_arch_dir = /dr3/iblogs
set-variable = innodb_log_files_in_group=2
#
# Размер файла журнала должен составлять
# около 15% от размера буферного пула,
set-variable = innodb_log_file_size=250M
set-variable = innodb_log_buffer_size=8M
#
innodb_flush_log_at_trx_commit=l
set-variable = innodb_lock_wait_timeout=50
#
# Уберите комментарий со следующих строк, если
# они должны использоваться.
#innodb_flush_method=fdatasync
#set-variable = innodb_thread_concurrency=5
Обратите внимание на то, что два файла данных размещены на разных дисках.
InnoDB будет заполнять табличное пространство, начиная с первого файла данных. В
некоторых случаях это позволяет повысить производительность базы данных, если не
все данные размещены на одном физическом диске. Размещение файлов журналов на
другом диске зачастую способствует повышению производительности. Для файлов дан-
ных InnoDB можно также использовать низкоуровневые разделы диска (низкоуровневые
устройства), что может позволить ускорить процессы ввода-вывода. См. раздел 9.15.2.
% Внимание!
Ъ В GNU/Linux x86 нельзя устанавливать слишком большой процент используемой памяти.
i; g l i b c позволит разрастись куче процесса и превысить стеки потоков, что приведет к сбою
5 сервера. Степень риска будет гораздо выше, если эта величина приблизится или превысит
ъ, значение 2 Гбайт:
Н/ innodb_buffer_pool_size
i + key_buffer \
|; + max__connections * (sort_buffer_size+read_buffer_size+binlog__cache__size)
y: + max_connections * 2 Мб
Каждый поток будет использовать стек (обычно 2 Мбайт, а в бинарных дистрибути-
вах от компании MySQL AB только 256 Кбайт) и, в худшем случае, также дополнитель-
ную память, равную sort_buf fer_size + read_buf fer_size.
530 Глава 9. Механизм хранения InnoDB

Начиная с версии MySQL 4.1, вы можете использовать до 64 Гбайт памяти в 32-


разрядной операционной системе Windows. См. описание innodb_buf fer_pool_awe_mem_mb
в разделе 9.5.
Как настроить другие параметры сервера mysqld?
Для большинства пользователей подойдут следующие стандартные значения:
[mysqld]
skip-external-locking
set-variable = max_connections=200
set-variable = read__buffer_size=lM
set-variable = sort_buffer=lM
#
# Размер key_buffer должен составлять
# 5-50% вашего ОЗУ, в зависимости
# от частоты использования
# таблицы MylSAM, a key_buffer_size +
# размер буферного пула InnoDB не должен
# превышать 80% вашего ОЗУ.
set-variable = key_buffer size=...

9.5. Опции запуска InnoDB


В этом разделе описаны серверные опции, связанные с InnoDB. В версии MySQL 4.0 и
выше их можно определить в виде —имя_опции= значение в командной строке или файлах
опций. До выхода версии MySQL 4.0 числовые опции должны были указываться с исполь-
зованием синтаксиса —set-va.riable=HMH_onu,HH= значение или -0 имя_опции= значение.
• innodb_additional_mem_pool_size. Размер пула памяти, который InnoDB исполь-
зует для хранения информации словаря данных и других внутренних структур
данных. Чем больше таблиц имеется в вашем приложении, тем больше информа-
ции нужно будет разместить в этом пуле. Если памяти в этом пуле окажется мало,
для InnoDB будет выделена память операционной системы, а в журнал регистра-
ции ошибок MySQL будут записываться предупреждающие сообщения. Значение
по умолчанию - 1 Мбайт.
• innodb_buf fer_pool_awe_mem_mb. Размер буферного пула (в мегабайтах), если он
установлен в памяти AWE 32-разрядной Windows. Доступен, начиная с версии
MySQL 4.1.0, и действителен только в среде 32-разрядной Windows. Если ваша
32-разрядная Windows поддерживает более 4 Гбайт памяти (так называемые ад-
ресные расширения Address Windowing Extentions, AWE), то с помощью этого
параметра вы сможете разместить буферный пул InnoDB в физической памяти
AWE. Максимально возможное значение для этого параметра составляет 64000.
Если этот параметр указан, innodb_buffer_pool_size будет соответствовать окну
в 32-разрядном адресном пространстве mysqld, в котором InnoDB будет отображать
память AWE. Наиболее предпочтительным значением для innodb_buffer_pool_size
является 500 Мбайт.
• innodb_buf fer_pool_size. Размер буфера памяти, который InnoDB использует для
занесения данных и индексов своих таблиц в кэш. Чем больше это значение, тем
меньше будет происходить обращений к диску для извлечения данных из таблиц.
9.5. Опции запуска InnoDB 531

На выделенном сервере баз данных этому параметру можно присвоить значение,


равное примерно 80% физической памяти компьютера. Однако присваивать
слишком большое значение не рекомендуется, так как при недостатке физической
памяти операционная система будет вынуждена сбрасывать часть информации на
диск.
• innodb_data__f ile_path. Пути к отдельным файлам данных и их размеры. Полный
путь к каталогу каждого файла данных можно получить посредством объедине-
ния innodb__data_home_dir с путем, который указанным в данном параметре. Раз-
меры файлов указываются в мегабайтах или гигабайтах (1 Гбайт = 1024 Мбайт)
путем добавления к величине размера суффикса М или G. Совокупный размер фай-
лов должен составлять как минимум 10 Мбайт. В некоторых операционных сис-
темах файлы должны иметь размер меньше 2 Гбайт. Если вы не укажете параметр
innodb_data_filejpath, то в этом случае будет создан автоматически расширяю-
щийся файл данных размером 10 Мбайт с именем ibdatal (справедливо для вер-
сии MySQL 4.0 и выше). Начиная с версии 3.23.44, в операционных системах,
поддерживающих файлы большого размера, можно задавать файл, размер которо-
го будет превышать 4 Гбайт. Вы можете также использовать низкоуровневые раз-
делы диска. См. раздел 9.15.2.
• innodb_data_home_dir. Общая часть пути к каталогу всех файлов данных InnoDB.
Если этот параметр не указывать, то по умолчанию для него будет использоваться
каталог данных MySQL. Если задать этот параметр как пустую строку, тогда в па-
раметре innodb_data__file__path можно будет использовать абсолютные пути к
файлам.
• innodb_fast_shutdown. По умолчанию перед закрытием InnoDB выполняет пол-
ную чистку и слияние буфера вставок. На это уходит несколько минут, а то и ча-
сов. Если этому параметру присвоить значение 1, то при закрытии InnoDB пропус-
тит упомянутую операцию. Этот параметр доступен, начиная с версий MySQL
3.23.44 и 4.0.1. Значение по умолчанию 1 используется, начиная с версии 3.23.50.
• innodb_file_to_threads. Количество потоков ввода-вывода в InnoDB. Обычно
этому параметру присваивается значение 4. Однако если в Windows этому пара-
метру присвоить большее значение, тогда можно будет добиться сокращения ко-
личества обращений к диску. В Unix увеличение этого значения не будет иметь
никакого эффекта. InnoDB всегда использует значение, принятое по умолчанию.
Этот параметр доступен, начиная с версии MySQL 3.23.37.
• innodb_file_per_table. Благодаря этой опции, InnoDB создает каждую новую
таблицу с помощью своего собственного файла . ibd (а не совместно используе-
мого табличного пространства), в котором сохраняются данные и индексы. См.
раздел 9.7.6. Эта опция доступна, начиная с версии MySQL 4.1.1.
• innodb_flush_log_at_trx_commit. Обычно этой опции присваивается значение 1,
в результате чего после фиксации транзакции информация журнала записывается
на диск, и фиксируются изменения, внесенные транзакцией. Это позволяет сохра-
нить данные в случае повреждения базы данных. Если у вас выполняются не-
большие транзакции, и вы готовы пожертвовать такой безопасностью, то этой оп-
ции можно присвоить значение 0 или 2, что позволит снизить количество обраще-
ний к диску. При нулевом значении запись сохраняется в журнальном файле,
532 Глава 9. Механизм хранения InnoDB

который сбрасывается на диск примерно один раз в секунду. Если присвоить зна-
чение 2, тогда запись в журнальный файл будет производиться во время выполне-
ния каждой транзакции. По умолчанию используется значение 1 (до выхода вер-
сии MySQL 4.0.13 по умолчанию использовалось нулевое значение).
• innodb_f lushjnethod. Эта опция работает только в системах Unix. Если устано-
вить для нее значение fdatasync, то InnoDB будет использовать функцию fsyncO
для сброса файлов данных и файлов журналов. Если присвоить значение O_DSYNC,
тогда InnoDB будет применять 0_SYNC для открытия и сброса файлов журналов, а
f sync () - для сброса файлов данных. Если указать 0_DIRECT (это значение дос-
тупно в некоторых версиях GNU/Linux, начиная с версии MySQL 4.0.14), тогда
InnoDB будет использовать его для открытия файлов данных, a fsyncO - для
сброса файлов данных и файлов журналов. Следует отметить, что InnoDB не ис-
пользует f datasynk или O_DSYNK по умолчанию, поскольку во многих операцион-
ных системах семейства Unix они не работают. Этот параметр доступен, начиная
с версии MySQL 3.23.40.
• innodb_force_recovery
|! Внимание!
|| Эта опция используется только в крайних случаях для сброса таблиц из поврежденной базы дан-
|| ных! Допустимыми значениями являются 1-6 (каждое из них описано в разделе 9.9.1). В целях
|| безопасности InnoDB запрещает пользователю изменять данные, когда значение этого napa-
lm метра больше 0. Параметр доступен, начиная с версии MySQL 3.23.44.

• innodb_lock_wait_timeout. Время тайм-аута (в секундах), на протяжении которо-


го транзакция InnoDB может ожидать блокировку до того, как будет произведен ее
откат. InnoDB автоматически обнаруживает взаимные блокировки транзакций в
своей таблице блокировок и выполняет их откат. Если вы используете LOCK
TABLES или работаете с другими механизмами хранения с транзакциями, отлич-
ными от InnoDB, то в случае взаимной блокировки InnoDB не сможет его обнару-
жить. В подобных ситуациях устранить проблему поможет тайм-аут. По умолча-
нию время тайм-аута составляет 50 секунд.
• innodb_log_archjdir. Каталог, в который будут записываться заархивированные
заполненные файлы журналов (при условии, что используется функция архивиро-
вания журналов). Значение этой опции на настоящий момент должно быть таким
же, как и для опции innodb_log_group_home_dir. Начиная с версии 4.0.6, эту оп-
цию можно опускать.
• innodb_log_archive. На данный момент этому параметру необходимо присваи-
вать нулевое значение. Поскольку восстановление из резервной копии MySQL
осуществляет с помощью своих собственных файлов журналов, архивировать
файлы журналов InnoDB не нужно. По умолчанию используется нулевое значение.
• innodb_log_buffer_size. Размер буфера, который используется в InnoDB для за-
писи журнальных файлов на диск. Лучше всего устанавливать размер в пределах
1-8 Мбайт. По умолчанию устанавливается размер 1 Мбайт. Большой буфер
журналов позволяет выполнять большие транзакции, не записывая журнал на
диск до завершения выполнения транзакции. Поэтому если вы работаете с
большими транзакциями, увеличение размера буфера журналов приведет к
сокращению количества дисковых операций ввода-вывода.
9.5. Опции запуска InnoDB 533

• innodb_log_file__size. Размер каждого журнального файла в группе журналов.


Общий размер журнальных файлов на 32-разрядных компьютерах не должен пре-
вышать 4 Гбайт. По умолчанию принимается размер 5 Мбайт. Размер лучше всего
подбирать таким, чтобы он составлял от 1 Мбайт до Ш от размера буферного пу-
ла, где N- это количество файлов журналов в группе. Чем больше это значение,
тем меньше придется выполнять контрольных сбросов содержимого на диск из
буферного пула, что приведет к сокращению количества дисковых операций вво-
да-вывода. Однако в этом есть и негативный момент: в случае сбоя на восстанов-
ление файлов больших размеров потребуется гораздо больше времени.
• innodb_log__f iles_in_group. Количество журнальных файлов в группе журналов.
InnoDB выполняет запись в файлы циклически. Этой опции рекомендуется при-
сваивать значение 2.
• innodb_log_group_home_dir. Путь к каталогу журнальных файлов InnoDB. Эта оп-
ция должна иметь то же значение, что и опция innodb_log_arch_dir. Если вы не
укажете параметры журнала InnoDB, то в каталоге данных MySQL по умолчанию
будут созданы два файла размером по 5 Мбайт с именами ib__logfileO и
ib_logfilel.
• innodb_max_dirty_pages_pct. Целое число в диапазоне от 0 до 100. По умолча-
нию используется 90. Главный поток в InnoDB пытается сбросить страницы из бу-
ферного пула, поэтому практически все эти страницы в определенный момент
времени нельзя будет сбросить. Опция доступна, начиная с версий 4.0.13 и 4.1.1.
Если вы имеете права суперпользователя (SUPER), то сможете изменять величину
этого процента во время работы сервера. Это можно сделать следующим образом:
SET GLOBAL innodb_max_dirty_pages_pct=3HaveHne;
• innodb_mirrored_log_groups. Количество идентичных копий групп журналов, ко-
торые хранятся для базы данных. На текущий момент этому параметру должно
быть присвоено значение 1.
• innodb_open_files. Этот параметр используется только в том случае, когда в
InnoDB задействовано множество табличных пространств. В нем указывается мак-
симальное количество файлов . ibd, которые InnoDB может одновременно держать
открытыми. Минимальное значение - 10. По умолчанию этому параметру при-
сваивается значение 300. Параметр доступен, начиная с версии MySQL 4.1.1.
Файловые дескрипторы, используемые для файлов .ibd, предназначены только
для InnoDB. Они не зависят от параметра сервера --open-files-limit и не влияют
на работу кэша таблиц.
• innodb_thread_concurrency. InnoDB пытается работать параллельно с нескольки-
ми потоками операционной системы внутри InnoDB, причем их количество долж-
но быть меньше или равно предельному значению, указанному в этой опции. По
умолчанию опции присваивается значение 8. Если показатели производительно-
сти невысокие, а команда SHOW INNODB STATUS выявила множество потоков, ожи-
дающих семафоры, это означает, что вы столкнулись с явлением, называемым
"пробуксовкой" потоков (thread thrashing). В подобных ситуациях необходимо
присвоить этому параметру меньшее или большее значение. Если вы работаете на
компьютере с большим количеством процессоров и дисков, этому параметру
можно присвоить более высокое значение, что позволит повысить степень ис-
534 Глава 9. Механизм хранения InnoDB

пользования ресурсов компьютера. Рекомендуется, чтобы это значение было рав-


но сумме количества процессоров и дисков вашей системы. Если значение будет
равно 500 или больше, вы не сможете выполнять проверку параллельного выпол-
нения операций. Параметр доступен, начиная с версий MySQL 3.23.44 и 4.0.1.

9.6. Создание табличного пространства InnoDB


Предположим, что вы установили MySQL и внесли в файл my.cnf необходимые кон-
фигурационные параметры InnoDB, Прежде чем запустить MySQL, необходимо убедить-
ся, что указанные каталоги для файлов данных и журналов InnoDB существуют, и что
сервер MySQL имеет права для доступа к этим каталогам. InnoDB может создавать толь-
ко файлы, но не каталоги. Проверьте также, имеется ли достаточно свободного дисково-
го пространства для файлов данных и журналов.
Лучше всего запускать сервер MySQL из командной строки во время создания базы
данных InnoDB, а не из оболочки mysqldsafe или в качестве службы Windows. Так вы
сможете наблюдать за происходящим и просматривать выходную информацию mysqld.
Если вы работаете в среде Unix, необходимо запустить демон mysqld. В Windows потре-
буется указать опцию --console.
Теперь, после того как механизм InnoDB первоначально сконфигурирован с помощью
файла опций, InnoDB создаст ваши файлы данных и файлы журналов. При этом будет
выведена примерно такая информация:
InnoDB: The f i r s t specified datafile /home/heikki/data/ibdatal
did not e x i s t :
InnoDB: a new database to be created!
InnoDB: Setting file /home/heikki/data/ibdatal size to 134217728
InnoDB: Database physically writes the file full: wait...
InnoDB: datafile /home/heikki/data/ibdata2 did not exist:
new to be created
InnoDB: Setting file /home/heikki/data/ibdata2 size to 262144000
InnoDB: Database physically writes the file full: wait...
InnoDB: Log file /home/heikki/data/logs/ib_logfileO did not exist:
new to be created
InnoDB: Setting log file /home/heikki/data/logs/ib_logfileO size to 5242880
InnoDB: Log file /home/heikki/data/logs/ib_logfilel did not exist:
new to be created
InnoDB: Setting log file /home/heikki/data/logs/ib_logfilel size to 5242880
InnoDB: Log file /home/heikki/data/logs/ib_logfile2 did not exist:
new to be created
InnoDB: Setting log file /home/heikki/data/logs/ib_logfile2 size to 5242880
InnoDB: Started
MySQLd: ready for connections
Здесь была создана новая база данных InnoDB. К серверу MySQL можно подключить-
ся посредством обычных клиентских программ MySQL, подобных mysql. Если работу
сервера MySQL завершить с помощью команды mysqladmin shutdown, будет выведена
следующая информация:
010321 18:33:34 mysqld: Normal shutdown
010321 18:33:34 mysqld: Shutdown Complete
InnoDB: Starting shutdown...
InnoDB: Shutdown completed
9.7. Создание таблиц InnoDB 535

Теперь можно просмотреть каталоги файлов данных и журналов, чтобы увидеть


созданные файлы. Каталог журналов будет содержать небольшой файл
ib_arch_log_0000000000. Этот файл появляется в результате создания базы данных, по-
сле чего InnoDB отключает архивирование журналов. Когда MySQL будет запущена
вновь, файлы данных и файлы журналов уже будут созданы, поэтому выводимая ин-
формация будет гораздо короче:
InnoDB: Started
mysqld: ready for connections

9.6.1. Проблемы, связанные с инициализацией InnoDB


Если при работе с файлом InnoDB выдает ошибку операционной системы, вероятно,
причиной может быть одна из перечисленных ниже:
• Вы не создали каталоги для файлов данных или журналов InnoDB.
• У mysqld нет прав для создания файлов в этих каталогах.
• mysqld не прочитал нужный файл my.cnf или my.ini и, соответственно, не полу-
чил указанные вами опции.
• Диск переполнен или превышена квота использования диска.
• Вы создали подкаталог, имя которого совпадает с указанным файлом данных.
• Синтаксическая ошибка в параметре innodb_data_home_dir или
innodb_data_file_path.
Если в тот момент, когда InnoDB пытается инициализировать свое табличное про-
странство или свои журнальные файлы что-то происходит не так, необходимо удалить
все файлы, созданные InnoDB. К ним относятся все файлы данных, все файлы журналов
и небольшой заархивированный журнальный файл. Если вы уже создали какие-то таб-
лицы InnoDB, вам придется удалить файлы . f rm этих таблиц (и любые файлы . ibd, если
вы работаете с множеством табличных пространств), которые находятся в каталогах баз
данных MySQL. После этого можно попробовать создать базе данных InnoDB еще раз.
Лучше всего запускать сервер MySQL из командной строки, дабы иметь возможность
наблюдать за происходящим.

9.7. Создание таблиц InnoDB


Предположим, что вы запустили клиент MySQL с помощью команды mysql t e s t .
Чтобы создать таблицу в формате InnoDB, в SQL-операторе создания таблицы потребу-
ется указать опцию ENGINE = InnoDB или TYPE = InnoDB:
CREATE TABLE customers (a INT, b CHAR (20), INDEX (a)) ENGINE=InnoDB;
CREATE TABLE customers (a INT, b CHAR (20), INDEX (a)) TYPE=InnoDB;
SQL-оператор создает таблицу и индекс по столбцу а табличного пространства
InnoDB, которое состоит из файлов данных, указанных в файле my.cnf. Кроме этого, в
подкаталоге t e s t каталога баз данных MySQL создается файл customers.frm. В свой
собственный словарь данных InnoDB добавляет запись для таблицы ' t e s t / c u s t o m e r s ' .
Эта запись означает, что вы можете создать таблицу с таким же именем customers в дру-
гой базе данных, и это не приведет к возникновению конфликта имен таблиц в рамках
InnoDB.
536 Глава 9. Механизм хранения InnoDB

С помощью команды SHOW TABLE STATUS для любой таблицы InnoDB можно запро-
сить количество свободного пространства в табличном пространстве InnoDB. Количество
свободного пространства будет выводиться в разделе Comment выходной информации
команды SHOW TABLE STATUS, например:
SHOW TABLE STATUS FROM t e s t LIKE ' c u s t o m e r s '
Обратите внимание, что статистические данные, которые команда SHOW выдает по
таблицам InnoDB, являются приблизительными. Они используются в целях оптимизации
SQL. А вот точными являются зарезервированные размеры таблиц и индексов, значения
которых указываются в байтах.

9.7.1. Как использовать транзакции InnoDB


в разных API-интерфейсах
По умолчанию каждый клиент, соединяющийся с сервером MySQL, начинает работу в
режиме автоматической фиксации, при котором каждый SQL-оператор выполняется авто-
матически. Чтобы использовать транзакции с несколькими операторами, можно выклю-
чить автоматическую фиксацию с помощью SQL-оператора SET AUTOCOMMIT=0 и использо-
вать COMMIT и ROLLBACK для фиксации или отката транзакции. Если вы хотите оставить ак-
тивным режим автоматической фиксации, можно поместить транзакции между START
TRANSACTION и COMMIT или ROLLBACK. До выхода версии MySQL 4.0.11 вместо START
TRANSACTION нужно было использовать ключевое слово BEGIN. В следующем примере по-
казаны две транзакции. Первая транзакция фиксируется, а выполнение второй отменяется.
s h e l l > mysql t e s t
Welcome t o t h e MySQL monitor. Commands end with ; or \g.
Your MySQL connection i d i s 5 t o s e r v e r v e r s i o n : 3.23.50-log
Type ' h e l p ; ' o r ' \ h ' f o r h e l p . Type ' \ c ' t o c l e a r t h e b u f f e r .
m y s q l > CREATE TABLE CUSTOMER (A I N T , В CHAR ( 2 0 ) , INDEX ( A ) )
- > TYPE=InnoDB;
Query OK, 0 rows a f f e c t e d ( 0 . 0 0 s e c )
mysql> BEGIN;
Query OK, 0 rows a f f e c t e d ( 0 . 0 0 s e c )
mysql> INSERT INTO CUSTOMER VALUES ( 1 0 , ' H e i k k i ' ) ;
Query OK, 1 row a f f e c t e d ( 0 . 0 0 s e c )
mysql> COMMIT;
Query OK, 0 rows a f f e c t e d ( 0 . 0 0 s e c )
mysql> SET AUTOCOMMIT=0;
Query OK, 0 rows a f f e c t e d ( 0 . 0 0 s e c )
mysql> INSERT INTO CUSTOMER VALUES ( 1 5 , ' J o h n ' ) ;
Query OK, 1 row a f f e c t e d ( 0 . 0 0 s e c )
mysql> ROLLBACK;
Query OK, 0 rows a f f e c t e d ( 0 . 0 0 s e c )
mysql> SELECT * FROM CUSTOMER;
+ 4- +
I A | B |
+ 4- +
I 10 | Heikki |
+
+ +
1 row in set (0.00 sec)
mysql>
9.7. Создание таблиц InnoDB 537

В таких API-интерфейсах, как PHP, Perl DBI/DBD, JDBC, ODBC или С, вы можете
посылать команды управления транзакциями (подобные COMMIT) серверу MySQL в виде
строк, подобно тому, как это делают и любые другие SQL-команды, например SELECT
или INSERT. В некоторых API-интерфейсах также предлагается разделять специальные
функции или методы фиксации и отката транзакций.

9.7.2. Преобразование таблиц MylSAM в формат InnoDB


Очень важно отметить, что преобразовывать системные таблицы MySQL в базе дан-
ных mysql (например, user или host) в тип InnoDB не следует. Системные таблицы
должны всегда оставаться таблицами типа My ISAM.
Если вы хотите, чтобы все ваши таблицы (не системные) создавались как таблицы
InnoDB, в раздел [mysqld] файла my.cnf или my.ini потребуется (начиная с версии
MySQL 3.23.43) добавить строку def ault-table-type=InnoDB.
В отличие от MylSAM, в InnoDB нет возможности оптимизировать создание отдельных
индексов, поэтому в этом формате не предусматривается выполнение операций экспор-
тирования и импортирования таблиц с последующим созданием индексов. Самый быст-
рый способ преобразовать таблицу в формат InnoDB - это напрямую вставить данные в
таблицу InnoDB, воспользовавшись оператором ALTER TABLE.. .TYPE=INNODB; можно
также создать пустую таблицу InnoDB с такой же структурой, и вставить строки с помо-
щью INSERT INTO...SELECT * FROM...
Если у вас имеются ограничения UNIQUE на вторичных ключах, то, начиная с версий
MySQL 3.23.52, ускорить процесс импортирования таблиц можно, если временно отклю-
чить проверку на уникальность на время выполнения операций: SET UNIQUE_CHECKS=O.
При работе с большими таблицами это позволит существенно сократить количество
дисковых операций ввода-вывода, поскольку InnoDB будет использовать свой буфер
вставки для ввода записей вторичного индекса в группу.
Чтобы контролировать процесс вставки, большие таблицы желательно вставлять по
частям:
INSERT INTO новая_таблица SELECT * FROM старая_таблица
WHERE ваш__ключ > значение AND ваш^ключ <= другое_значение;
После того, как все записи будут вставлены, таблицы можно будет переименовать.
На время преобразования больших таблиц необходимо задавать достаточно большой
размер буферного пула InnoDB, дабы сократить количество дисковых операций ввода-
вывода. С другой стороны, размер буфера не должен превышать 80% от физической па-
мяти компьютера. Можно также увеличить размер файлов журналов InnoDB.
Убедитесь в том, что у вас имеется достаточно свободного места для табличного
пространства: таблицы InnoDB занимают гораздо больше места, чем таблицы MylSAM.
Если во время выполнения команды ALTER TABLE будет занято все свободное дисковое
пространство, произойдет откат, на осуществление которого может потребоваться не-
сколько часов, если диск окажется заполненным. Во время вставок InnoDB использует
буфер вставки, который позволяет объединить записи вторичного индекса с индексами в
группах. Это позволит сократить количество дисковых операций ввода-вывода. При от-
кате транзакции такой механизм не используется, поэтому откат может занять раз в 30
больше времени, чем вставка.
В том случае, если началось выполнение отката, а в вашей базе данных не содержит-
ся ценная информация, лучше всего прервать этот процесс и не ждать, пока завершится
538 Глава 9. Механизм хранения InnoDB

выполнение миллионов дисковых операций ввода-вывода. Полностью эта процедура


описана в разделе 9.9.1.

9.7.3. Как работают столбцы AUTOJNCREMENT в InnoDB


Если в вашей таблице имеется столбец AUTO_INCREMENT, то для обработки таблицы
InnoDB в словаре данных будет находиться специальный счетчик, называемый счетчи-
ком автоматического приращения (auto-increment counter). Этот счетчик используется
для присвоения столбцу новых значений. Счетчик автоматического приращения хранит-
ся только в основной памяти, а не на диске.
Чтобы инициализировать счетчик для таблицы Т, в которой содержится столбец
AUTO_INCREMENT с именем ai_col, InnoDB использует следующий алгоритм. После запус-
ка сервера, когда пользователь сделает первую вставку в таблицу Т, InnoDB выполнит
эквивалент этого оператора:
SELECT MAX ( a i _ c o l ) FROM T FOR UPDATE;

Значение, полученное оператором, увеличивается на единицу и присваивается столб-


цу и счетчику автоматического приращения. Если таблица пуста, ему будет присвоено
значение 1. Если счетчик не инициализирован и пользователь выполняет оператор SHOW
TABLE STATUS, который показывает выходную информацию для таблицы т, счетчик ини-
циализируется (без увеличения его значения) и сохраняется для будущих вставок. За-
метьте, что в этой инициализации мы выполняем обычное чтение с эксклюзивной бло-
кировкой, которая продолжается до завершения выполнения транзакции.
Эту же последовательность действий InnoDB выполняет и для инициализации счет-
чика автоматического приращения для вновь созданной таблицы.
Имейте в виду, что если пользователь в столбце AUTO_INCREMENT определит значение
NULL или 0 в INSERT, то InnoDB будет обрабатывать строку таким образом, как будто это
значение вообще не было определено и сгенерирует для столбца новое значение.
Если счетчик инициализирован, то когда пользователь попытается вставить строку,
явным образом определяющую значение столбца, и это значение окажется больше, чем
текущее значение счетчика, то последнему будет присвоено значение, определенное для
столбца. Если пользователь явным образом не определит значение, InnoDB увеличит
значение счетчика на единицу, а столбцу присвоит новое значение.
При обращении к счетчику автоматического приращения InnoDB использует специаль-
ную блокировку таблицы на уровне AUTO-INC, которая будет продолжаться до завершения
выполнения текущего SQL-оператора, но не до завершения выполнения транзакции. Для
этой цели была использована стратегия, направленная на улучшение параллельной обра-
ботки вставок в таблицу, которая содержит столбец AUTO_INCREMENT. Две транзакции не
могут иметь блокировку AUTO_INC в одной и той же таблице одновременно.
В последовательности значений, присвоенных столбцу AUTO__INCREMENT, могут появ-
ляться пропуски. Это связано с откатами транзакций, получающих значения из счетчика.
В тех случаях, когда пользователь присваивает столбцу отрицательное значение или
если значение оказывается больше, чем максимально возможное значение для данного
целочисленного типа, поведение механизма автоматического приращения может стать
непредсказуемым.
9.7. Создание таблиц InnoDB 539

9,7.4. Ограничения внешнего ключа (FOREIGN KEY)


Начиная с версии MySQL 3.23.43b, в InnoDB были введены ограничения внешних
ключей.
Синтаксис описания ограничения внешнего ключа в InnoDB выглядит так:
[CONSTRAINT символ] FOREIGN KEY [идентификатор] {имя_индексного_столбца, ...)
REFERENCES tbl_j\ame {имя_индексного_столбца, ...)
[ON DELETE {CASCADE | SET NULL | NO~ACTION | RESTRICT | SET DEFAULT}]
[ON UPDATE {CASCADE | SET NULL | NO ACTION | RESTRICT | SET DEFAULT}]

Обе таблицы должны быть таблицами формата InnoDB. Таблица, производящая ссыл-
ку, должна иметь индекс, в котором столбцы внешнего ключа должны быть указаны в
первых столбцах в одинаковом порядке. Таблица, на которую производится ссылка,
должна иметь индекс, в котором столбцы, на которые производится ссылка, должны
быть указаны в первых столбцах в одинаковом порядке. Внешние ключи не поддержи-
вают столбцы с индексами в префиксах.
InnoDB не создает автоматически индексы на внешних или на ссылочных ключах -
вы должны их создать самостоятельно. Благодаря индексам проверки внешнего ключа
могут осуществляться быстро и без сканирования таблицы.
Соответствующие столбцы внешнего и ссылочного ключей в таблице InnoDB должны
содержать данные одинакового типа, что позволит сравнивать их, не преобразовывая
типы. Размер и знак целочисленных типов должны быть одинаковыми. Длина стро-
ковых типов может быть различной. Если вы определяете действие SET NULL, убедитесь
в том, что столбцы в дочерней таблице не объявлены как NOT NULL.
Если MySQL выдает ошибку с номером 1005 после оператора CREATE TABLE, а в
строке сообщения об ошибке присутствует ссылка на ошибку с номером 150, это свиде-
тельствует о сбое при создании таблицы, который был вызван тем, что ограничения
внешнего ключа не были сформированы надлежащим образом. Аналогично и для опера-
тора ALTER TABLE: если возникает ошибка при выполнении оператора и в сообщении
присутствует ссылка на ошибку с номером 150, это означает, что описание внешнего
ключа для преобразовываемой таблицы было сформировано неправильно. Начиная с
версии MySQL 4.0.13, можно использовать команду SHOW INNIDB STATUS для вывода де-
тальных сведений по последней ошибке внешнего ключа InnoDB на сервере.
Начиная с версии MySQL 3.23.50, InnoDB не проверяет ограничения внешнего ключа
по значениям, содержащимся в столбце NULL.
Отклонение от стандартов SQL. Если в родительской таблице присутствует не-
сколько строк с одинаковым значением ссылочного ключа, InnoDB проверяет внешний
ключ так, как если бы не существовали другие родительские строки с тем же значением
ключа. Например, если вы определили ограничение RESTRICT, и если существует дочер-
няя строка с несколькими родительскими строками, то InnoDB не разрешит удалить ка-
кую-либо родительскую строку.
Начиная с версии MySQL 3.23.50, с ограничением внешнего ключа можно также свя-
зывать конструкции ON DELETE CASCADE или ON DELETE SET NULL. Соответствующие па-
раметры ON UPDATE доступны в версии 4.0.8 и выше. Если определить конструкцию ON
DELETE CASCADE, и если будет удалена строка в родительской таблице, то InnoDB удалит
автоматически все те строки в дочерней таблице, значения внешнего ключа которых
будут равны значениям ссылочного ключа в родительской строке. Если определить
предложение ON DELETE SET NULL, строки дочерней таблицы будут обновлены автома-
540 Глава 9. Механизм хранения InnoDB

тически, поэтому столбцам во внешнем ключе будет присвоено значение NULL. SET
DEFAULT хотя и анализируется, но игнорируется.
Операции каскадирования InnoDB выполняет в соответствии с алгоритмом поиска в
глубину (depth-first algorithm), который основан на записях в индексах в соответствии с
ограничениями внешнего ключа.
Отклонение от стандартов SQL. Если операция ON UPDATE CASCADE или ON UPDATE
NULL возвращается к обновлению одной и топ лее таблицы, которая уже была обновлена
во время выполнения каскадирования, то эта операция будет работать как RESTRICT. Это
означает, что вы не сможете использовать самоотносимые операции ON UPDATE CASCADE
или ON UPDATE SET NULL. Это необходимо для того, чтобы предотвратить бесконечные
циклы, возникающие в результате каскадных обновлений. С другой стороны, начиная с
версии MySQL 4.0.13, доступно самоотносимая операция ON DELETE SET NULL. Самоот-
носимая операция ON DELETE CASCADE была доступно с момента реализации ON DELETE.
Далее показан простой пример установления отношения между таблицами parent и
child посредством внешнего ключа с одним столбцом:
CREATE TABLE p a r e n t ( i d INT NOT NULL,
PRIMARY KEY (id)
) TYPE=INNODB;
CREATE TABLE c h i l d ( i d INT, p a r e n t _ i d INT,
INDEX p a r _ i n d ( p a r e n t _ i d ) ,
FOREIGN KEY (parent_id) REFERENCES p a r e n t ( i d )
ON DELETE CASCADE
) TYPE=INNODB;
Ниже представлен более сложный пример, в котором таблица product_order имеет
внешние ключи для двух других таблиц. Один внешний ключ ссылается на индекс с
двумя столбцами в таблице product. Другой ключ ссылается на индекс с одним столб-
цом в таблице customer:
CREATE TABLE p r o d u c t ( c a t e g o r y INT NOT NULL, i d INT NOT NULL,
p r i c e DECIMAL,
PRIMARY K E Y ( c a t e g o r y , i d ) ) TYPE=INNODB;
CREATE TABLE c u s t o m e r ( i d INT NOT NULL,
PRIMARY KEY ( i d ) ) TYPE=INNODB;
CREATE TABLE p r o d u c t _ o r d e r (no INT NOT NULL AUTO_INCREMENT,
p r o d u c t _ c a t e g o r y INT NOT NULL,
p r o d u c t _ _ i d INT NOT NULL,
c u s t o m e r _ i d INT NOT NULL,
PRIMARY KEY(no),
INDEX (product_category, product_id),
FOREIGN KEY (product_category, product_id)
REFERENCES product(category, id)
ON UPDATE CASCADE ON DELETE RESTRICT,
INDEX (customer_id),
FOREIGN KEY (customer_id)
REFERENCES customer(id)) TYPE=INNODB;
Начиная с версии MySQL 3.23.50, InnoDB позволяет добавлять новое ограничение
внешнего ключа в таблицу, используя команду ALTER TABLE:
9.7. Создание таблиц InnoDB 541

ALTER TABLE имя__таблицы


ADD [CONSTRAINT символ] FOREIGN KEY [идентификатор] (имя_индексного_столбца,...)
REFERENCES t b l _ n a m e {имя_индексного_столбца, ...)
[ON DELETE {CASCADE | SET NULL | NO ACTION | RESTRICT | SET DEFAULT}]
[ON UPDATE {CASCADE | SET NULL | NO ACTION | RESTRICT | SET DEFAULT}]

He забывайте о том, что сначала нужно создать все необходимые индексы. По-
мимо этого, с помощью команды ALTER TABLE можно добавлять в таблицу ограничение
на самоотносимый внешний ключ.
Начиная с версии MySQL 4.0.13, InnoDB поддерживает выполнение команды ALTER
TABLE для удаления внешних ключей:
ALTER TABLE имя_таблицы DROP FOREIGN KEY символ_внешнего_ключа;

Удалить внешний ключ можно также, сославшись на имя CONSTRAINT, включенное в


конструкцию FOREIGN KEY при создании внешнего ключа. (Начиная с версии MySQL
4.0.18, ограничению можно присваивать имя.) В противном случае при создании внеш-
него ключа значение символ_внешнего_ключа генерируется внутренне. Чтобы найти сим-
вол для удаления внешнего ключа, воспользуйтесь оператором SHOW CREATE TABLE, на-
пример:
mysql> SHOW CREATE TABLE i b t e s t l l c \ G
*************************** im r o w ***************************
Table: ibtestllc
Create Table: CREATE TABLE ч ibtestllc v (
Ч Ч
А int(ll) NOT NULL auto_increment,
4 4
D int(ll) NOT NULL default '0',
4 V
B varchar(200) NOT NULL default ",
N 4
C varchar(175) default NULL,
PRIMARY KEY ( 4 A\V D \ * B 4 ) ,
KEY 4 B N ( 4 B\4 C N ) ,
KEY Ч Г ( % C % ),
CONSTRAINT ^ 0 _ 3 8 7 7 5 4 FOREIGN KEY ( V A \ 4 D 4 )
REFERENCES 4 i b t e s t l l a N f A \ 4 D 4 )
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT N 0 _ 3 8 7 7 6 4 FOREIGN KEY ( 4 B \ ^ C )
4 4 N
REFERENCES 4 b t e s t l l a f B \ C )
ON DELETE CASCADE ON UPDATE CASCADE
) TYPE=InnoDB C H A R S E T = l a t i n l
1 rowi n s e t (0.01 s e c )
mysql> ALTER TABLE i b t e s t l l c DROP FOREIGN KEY 0_38775;

Начиная с версии MySQL 3.23.50, синтаксический анализатор InnoDB позволяет ис-


пользовать обратные кавычки ( ) , обрамляющие имена таблиц и столбцов в конструкции
FOREIGN KEY.. .REFERENCES... Начиная с версии MySQL 4.0.5, синтаксический анализатор
InnoDB способен учитывать параметры системной переменной lower_case_table_names.
До выхода версии MySQL 3.23.50 команды ALTER TABLE и CREATE INDEX не использо-
вались для тех таблиц, в которых были установлены ограничения внешнего ключа или
на которые имелись ссылки в ограничениях внешних ключей: команда ALTER TABLE уда-
ляет все ограничения внешних ключей, определенные в таблице. Команду ALTER TABLE
не следует применять в отношении тех таблиц, на которые имеются ссылки. Чтобы из-
менить логическую структуру, вместо этой команды необходимо использовать DROP
542 Глава 9. Механизм хранения InnoDB

TABLE и CREATE TABLE. При выполнении команды ALTER TABLE MySQL может использовать
команду RENAME TABLE, что может привести к нарушению ограничений внешнего ключа,
ссылающегося на таблицу. Оператор CREATE INDEX в MySQL обрабатывается так же, как и
ALTER TABLE, поэтому приведенные выше ограничения действительны и для него.
Начиная с версии MySQL 3.23.50, InnoDB возвращает определения внешнего ключа
таблицы в виде части выходных данных оператора SHOW CREATE TABLE:
SHOW CREATE TABLE имя_таблицы;
В этой версии mysql dump также генерирует корректные определения таблиц для фай-
ла дампа и не забывает о внешних ключах.
Вывести ограничения внешнего ключа для таблицы можно следующим образом:
SHOW TABLE STATUS FROM имя_базы_данных LIKE 'имя_таблицы*
Ограничения внешнего ключа выводятся в виде списка в столбце Comment (коммента-
рий) вывода.
При проверке внешних ключей InnoDB устанавливает совместно используемые бло-
кировки на уровне строки на родительских или дочерних записях, подлежащих провер-
ке. Проверка ограничений внешнего ключа для таблиц InnoDB осуществляется немед-
ленно и не откладывается до фиксации транзакции.
Чтобы облегчить повторную загрузку файлов дампа для таблиц, имеющих отноше-
ние к внешнему ключу, mysql dump автоматически включает в вывод дампа оператор для
присвоения параметру FOREIGN_KEY_CHECKS значения 0 (как в версии MySQL 4.1.1). Это
позволяет избежать возникновения проблем с таблицами, которые должны индивиду-
ально повторно перезагружаться во время повторной загрузки дампа. В более ранних
версиях переменную можно было отключить вручную непосредственно в mysql в про-
цессе загрузки файла данных, как показано далее:
mysql> SET FOREIGN_KEY_CHECKS = 0;
mysql> SOURCE имя_файла_дампа;
mysql> SET FOREIGN_KEY_CHECKS = 1;
Подобным образом вы сможете импортировать таблицы в любом порядке, если в
файле дампа будут содержаться таблицы, неупорядоченные для внешних ключей. Это
позволит повысить скорость выполнения импорта. Параметр FORE IGN_KEY_CHECKS досту-
пен, начиная с версии MySQL 3.23.52. и MySQL 4.O.3.
Присвоение параметру FOREIGN_KEY_CHECKS нулевого значения будет полезно для то-
го, чтобы игнорировать ограничения внешнего ключа во время выполнения операции
LOAD DATA.
InnoDB позволяет удалять любую таблицу, даже если это приведет к нарушению ог-
раничений внешнего ключа, ссылающегося на таблицу. При удалении таблицы удаляют-
ся и ограничения, описанные в операторе, с помощью которого она была создана.
Если удаленная таблица создается повторно, ее описание должно согласоваться с ог-
раничениями внешнего ключа, который на нее ссылается. В этой таблице необходимо
правильно задать имена и типы столбцов; она должна также иметь индексы ключей, на
которые производится ссылка, о чем было сказано выше. Если эти условия не будут
удовлетворены, MySQL выдаст ошибку с номером 1005 и ссылку на ошибку с номером
150 в строке сообщения об ошибке.
9.7. Создание таблиц InnoDB 543

9.7.5. InnoDB и репликация в MySQL


Репликация в MySQL для InnoDB работает также, как и в таблицах MylSAM. Ее можно
использовать и несколько иначе: когда тип подчиненной таблицы отличается от исход-
ного типа главной таблицы. Например, можно реплицировать модификации главной
таблицы InnoDB в подчиненную таблицу My ISAM.
Чтобы установить новую подчиненную таблицу для главной таблицы, необходимо
сделать копию табличного пространства InnoDB и файлов журналов, а так же файлов
.frm и таблиц InnoDB, и переместить копии в подчиненную таблицу. Чтобы безошибоч-
но проделать эту процедуру, изучите материалы раздела 9.10.
Если вы можете закрыть главную или существующую подчиненную таблицу, вы мо-
жете сформировать холодную резервную копию табличного пространства InnoDB и фай-
лов журналов, и использовать ее для настройки подчиненной таблицы. Чтобы иметь
возможность создавать новые подчиненные таблицы, не отключая серверы, можно ис-
пользовать коммерческий инструмент InnoDB Hot Backup.
На репликацию InnoDB распространяются некоторые несущественные ограничения:
• LOAD TABLE FROM MASTER не работает для таблиц типа InnoDB. С этим можно спра-
виться двумя способами: 1) выполняя дамп таблицы на главном сервере и импор-
тируя файл дампа на подчиненный сервер; 2) используя команду ALTER TABLE
имя_таблицы TYPE=MyISAM на главном сервере перед настройкой репликации с по-
мощью LOAD TABLE имя_таблицы FROM MASTER, а затем используя ALTER TABLE ДЛЯ
последующего преобразования главной таблицы обратно к типу InnoDB.
• До выхода версии MySQL 4.0.6 команда SLAVE STOP не распознавала границы
транзакции с несколькими операторами. Незавершенная транзакция будет откло-
нена, и следующая команда SLAVE START выполнит только оставшуюся часть
транзакции. Это приведет к неудачному выполнению репликации.
• До выхода версии MySQL 4.0.6 аварийный отказ подчиненного сервера во время
выполнения транзакции с несколькими операторами приводил к возникновению
тех же проблем, что и при выполнении команды SLAVE STOP.
• До выхода версии MySQL 4.0.11 репликация оператора SET FOREIGN_KEY_CHECKS=0
работала некорректно.
Большинство этих ограничений можно обойти, если использовать более новые вер-
сии сервера, к которым упомянутые ограничения не применимы.
Неудачно выполненные на главном сервере транзакции вообще не влияют на репли-
кацию. Репликация MySQL основана на бинарном журнале, в котором MySQL записы-
вает SQL-операторы, модифицирующие данные. Подчиненная таблица считывает би-
нарный журнал главной таблицы и выполняет те же SQL-операторы. Однако операторы,
выполняющиеся во время транзакции, не записываются в бинарный журнал до заверше-
ния выполнения транзакции. После завершения ее выполнения в бинарный журнал зано-
сятся сразу все операторы. Например, если оператор был выполнен неудачно вследствие
искажения внешнего ключа или по причине отката транзакции, то ни один SQL-
оператор не будет записан в бинарный журнал, и на подчиненном сервере транзакция
вообще не будет выполнена.
544 Глава 9. Механизм хранения InnoDB

9.7.6. Использование табличного пространства


для каждой таблицы
Начиная с версии MySQL 4.1.1, каждую таблицу InnoDB и ее индексы можно сохра-
нять в своем собственном файле. Эта возможность называется "множественными таб-
личными пространствами", поскольку каждая таблица обладает своим собственным таб-
личным пространством.
f На заметку!
'i Если вы используете MySQL 4.1.1 или выше, вам будет довольно трудно вернуться к ранним
'if версиям 4.0. или 4.1.0! Это связано с тем, что в ранних версиях поддержка множественных таб-
j£ личныъ пространств для InnoDB отсутствует.

Если вам нужно будет перейти к версии 4.0, то в этом случае вам придется извлечь
дампы таблиц и повторно создать все табличное пространство InnoDB. Если у вас нет
созданных новых таблиц InnoDB для MySQL 4.1.1 и выше, и требуется быстро перейти к
ранним версиям, можно просто вернуться к версии MySQL 4.0.18 или более поздней в
линейке 4.0. Прежде чем перейти к версии в линейке 4.О., необходимо закрыть все кли-
ентские соединения с сервером mysqld, который должен быть понижен в версии, и по-
зволить ему осуществить очистку и операции слияния буферных вставок. После этого
команда SHOW INNODB STATUS покажет, что основной поток находится в состоянии
waiting for server activity. Затем можно будет завершить работу mysqld и запустить
версию 4.0.18 или более позднюю в линейке 4.0. Тем не менее, мы не рекомендуем пе-
реходить напрямую к более ранней версии, поскольку такой переход еще не изучен в
достаточной мере.
Активизировать множество табличных пространств можно, если в раздел [mysqld]
файла my. cnf добавить следующую строку:
[mysqld]
innodb_file_per_table
После перезапуска сервера InnoDB будет сохранять каждую вновь созданную таблицу
в ее собственном файле имя_таблицы.ibd, который будет расположен в каталоге баз
данных, куда принадлежит таблица. Подобное происходит и в механизме хранения
MylSAM, однако MylSAM делит таблицу на файл данных имя_таблицы.ЖЪ и файл индекса
имя_таблицы.MYI. В InnoDB данные и индексы сохраняются в файле .ibd. Файл
имя_таблицы. f rm создается так же, как и обычно.
Если удалить строку innodb_file_per_table из файла my.cnf и перезапустить сер-
вер, то InnoDB снова создаст таблицы внутри файлов совместно используемого таблич-
ного пространства.
innodb_f ile_per__table оказывает влияние только на создание таблиц. Если запустить
сервер без этой опции, новые таблицы хотя и будут созданы в файлах . idb, однако вы все
равно сможете обращаться к таблицам, существующим в табличном пространстве общего
использования. Если удалить этот параметр, то новые таблицы будут созданы в табличном
пространстве общего использования, однако вы все равно сможете обращаться к любой
таблице, созданной с применением множественного табличного пространства.
Для InnoDB всегда необходимо табличное пространство общего использования. Для
работы InnoDB недостаточно одних лишь файлов .idb. В табличном пространстве обще-
го использования содержатся файлы ibdata, в которые InnoDB заносит свой внутренний
словарь данных и журналы отмены выполненных действий.
9.7. Создание таблиц InnoDB 545

Нельзя свободно перемещать файлы .ibd между каталогами баз данных, как это
можно сделать с файлами таблиц MylSAM. На то есть два объяснения: 1) описание табли-
цы хранится в табличном пространстве общего использования InnoDB; 2) механизм
InnoDB должен сохранять последовательность идентификаторов транзакций и порядок
номеров в журналах.
В пределах установленной копии MySQL можно перемещать файл . ibd и связанную
с ним таблицу из одной базы данных в другую с помощью знакомого вам оператора
RENAME TABLE:
RENAME TABLE старое_имя_базы_данных.имя_таблицы
TO новое_имя_базы_данных. имя_та блицы;
Если у вас имеется чистая резервная копия файла . ibd, этот файл можно восстано-
вить в MySQL:
1. Выполните оператор ALTER TABLE:
ALTER TABLE имя_таблицы DISCARD TABLESPACE;
Внимание! Текущий файл . ibd будет удален.
2. Переместите резервную копию файла .ibd обратно в соответствующий каталог
базы данных.
3. Выполните оператор ALTER TABLE:
ALTER TABLE имя_таблицы IMPORT TABLESPACE;
В данном контексте чистая резервная копия файла . idb означает, что:
• В этом файле не существует незафиксированных модификаций, выполненных
транзакциями.
• В этом файле не существуют несоединенные записи буфера вставок.
• Во время чистки из него были удалены все индексные записи, обозначенные для
удаления.
• mysqld сбросил все модифицированные станицы файла . ibd из буферного пула в
файл.
Чистую резервную копию файла . ibd можно подготовить следующим образом:
1. Остановите работу сервера mysqld и зафиксируйте все транзакции.
2. Подождите, пока после выполнения команды SHOW INNODB STATUS не будет пока-
зано, что в базе данных отсутствуют активные транзакции, и что основной поток
InnoDB пребывает в состоянии Waiting for server a c t i v i t y . После этого вы
сможете сделать копию . ibd файла.
Другой способ создания чистой резервной копии файла . ibd заключается в исполь-
зовании коммерческого инструмента InnoDB HOT Backup:
1. Воспользуйтесь InnoDB HOT Backup для резервного копирования InnoDB.
2. Запустите второй сервер mysqld для резервной копии, чтобы осуществить чистку
файлов . ibd в резервной копии.
В нашем списке TODO запланировано позволить перемещать чистые файлы . ibd в
другую установленную копию MySQL. Для этого потребуется перенастроить идентифи-
каторы транзакций и проверить последовательность номеров журналов в файле . ibd.
546 Глава 9. Механизм хранения lnnoDB

9.8. Добавление и удаление файлов данных


и файлов журналов InnoDB
В этом разделе показано, что можно сделать, если табличное пространство lnnoDB
оказалось заполненным или если вы хотите изменить размер файлов журналов.
Начиная с версий MySQL 3.23.50 и MySQL 4.0.2, самый простой способ увеличения
размера табличного пространства InnoDB состоит в том, чтобы придать ему статус авто-
матически расширяющегося. Для последнего файла данных в описании табличного про-
странства можно указать параметр autoextend. Когда будет занято все пространство,
InnoDB увеличит размер файла автоматически на 8 Мбайт.
Можно поступить иначе, а именно - увеличить размер табличного пространства, до-
бавив еще один файл данных. Для этого потребуется завершить сервер MySQL, изме-
нить файл my.cnf, добавив новый файл данных в конце строки innodb_data_file_path,
и запустить сервер снова.
Если последний файл данных уже имеет ключевое слово autoextend, в файле my.cnf
должен учитываться новый размер последнего файла данных. Узнайте, какой размер
должен иметь файл, округлите эту величину (1024*1024 байт = 1 Мбайт) и укажите ее в
параметре innodb_data_file_path. Затем вы сможете добавить другой файл данных.
Помните, что только последний файл данных в innodb_data_f ile_path может быть ука-
зан как автоматически расширяющийся.
Для примера предположим, что табличное пространство имеет только один автома-
тически расширяющийся файл данных ibdatal:
innodb_data_home_dir =
innodb_data_file_path = /ibdata/ibdatal:ЮМ:autoextend
Допустим, что с течением времени размер этого файла данных увеличился до
988 Мбайт. Далее показана строка конфигурации после добавления другого автоматиче-
ски расширяющегося файла данных.
innodb_data__home_dir =
innodb_data_file_path = /ibdata/ibdatal:988M;/disk2/ibdata2:50M:autoextend
При добавлении нового файла в табличное пространство необходимо убедиться в
том, что он не существует. InnoDB создаст и инициализирует этот файл после перезапус-
ка сервера.
На данный момент удалить файл данных из табличного пространства нельзя. Чтобы
уменьшить размер табличного пространства, выполните следующие действия:
1. С помощью mysqldump подготовьте дамп всех таблиц InnoDB.
2. Остановите сервер.
3. Удалите из табличного пространства все существующие файлы.
4. Сконфигурируйте новое табличное пространство.
5. Перезапустите сервер.
6. Импортируйте файлы дампа.
Если вам потребуется изменить количество или размер файлов журналов InnoDB, для
этого будет необходимо остановить работу сервера MySQL и удостовериться, что сервер
завершился без каких-либо ошибок. Затем нужно скопировать старые файлы журналов в
безопасное место - на случай, если по завершении работы будут выявлены ошибки и
9.9. Создание резервных копий и восстановление базы данных InnoDB 547

если они вам понадобятся для восстановления табличного пространства. Затем следует
удалить старые файлы журналов из их каталога, внести изменения в файл my. cnf и снова
запустить MySQL. Теперь во время запуска raysqld увидит, что ни один файл журнала не
существует, и выдаст сообщение о создании новых файлов журналов.

9.9. Создание резервных копий


и восстановление базы данных InnoDB
Чтобы обеспечить безопасное управление базами данных, необходимо регулярно
создавать резервные копии.
Существует интерактивный инструмент создания резервных копий InnoDB Hot
Backup, который можно использовать для резервного копирования своей базы данных
InnoDB во время ее работы. InnoDB Hot Backup не требует закрывать базу данных или
устанавливать блокировки, то есть обычное функционирование базы данных не наруша-
ется. InnoDB Hot Backup является дополнительным коммерческим инструментом, ли-
цензия которого в расчете на один компьютер с сервером MySQL стоит 390 евро. Чтобы
получить дополнительную информацию и просмотреть экранные снимки экрана, посе-
тите домашнюю страницу InnoDB Hot Backup по адресу:
http://www.InnoDB.com/order.html
Если есть возможность остановить сервер MySQL, а затем создать бинарную резерв-
ную копию своей базы данных, выполните следующие действия:
1. Завершите сервер MySQL и удостоверьтесь, что он завершился без ошибок.
2. Скопируйте все свои файлы данных в безопасное место.
3. Скопируйте все свои файлы журналов InnoDB в безопасное место.
4. Скопируйте свой файл конфигурации my. cnf в безопасное место.
5. Скопируйте все файлы . f rm ваших таблиц InnoDB в безопасное место.
Таблицы типа InnoDB поддерживают репликацию, поэтому ее возможностями можно
воспользоваться для создания и хранения копий базы данных на площадках, обслужи-
вающих базы данных, на которых требуется поддерживать высокую скорость доступа.
Кроме создания бинарных резервных копий необходимо также регулярно выполнять
дамп своих таблиц с помощью mysqldump. Дело в том, что повреждение бинарного файла
для пользователя происходит практически незаметно. Таблицы, перенесенные в дамп,
сохраняются в текстовых файлах, поэтому обнаружить ошибку в данных будет гораздо
проще. Кроме этого, поскольку они представлены в довольно простом формате, вероят-
ность серьезного повреждения данных будет меньше, mysqldump принимает опцию
— single-transsaction, которая позволяет извлекать непротиворечивый снимок дан-
ных, не блокируя при этом других клиентов.
Чтобы восстановить базу данных InnoDB из описанной выше бинарной резервной ко-
пии, потребуется запустить сервер MySQL с включенной функцией бинарной регистра-
ции. Впоследствии, в процессе восстановления, вы сможете использовать бинарный
журнал для мгновенного получения резервной копии базы данных:
mysqlbinlog имя_хоста-Ып. 123 | mysql
Чтобы восстановить работу сервера MySQL после сбоя, достаточно просто переза-
пустить его. InnoDB автоматически произведет проверку журналов и восстановит базу
548 Глава 9. Механизм хранения InnoDB

данных с повтором всех завершенных на данный момент транзакций. Кроме этого,


InnoDB автоматически отклонит незавершенные на момент сбоя транзакции. Во время
процесса восстановления InnoDB будет выводить примерно следующую информацию:
InnoDB: Database was not shut down normally.
InnoDB: Starting recovery from log files...
InnoDB: Starting log scan based on checkpoint at
InnoDB: log sequence number 0 13674004
InnoDB: Doing recovery: scanned up to log sequence number 0 13739520
InnoDB: Doing recovery: scanned up to log sequence number 0 13805056
InnoDB: Doing recovery: scanned up to log sequence number 0 13870592
InnoDB: Doing recovery: scanned up to log sequence number 0 13936128

InnoDB: Doing recovery: scanned up to log sequence number 0 20555264


InnoDB: Doing recovery: scanned up to log sequence number 0 20620800
InnoDB: Doing recovery: scanned up to log sequence number 0 20664 692
InnoDB: 1 uncommitted transaction(s) which must be rolled back
InnoDB: Starting rollback of uncommitted transactions
InnoDB: Rolling back trx no 16745
InnoDB: Rolling back of trx no 16745 completed
InnoDB: Rollback of uncommitted transactions completed
InnoDB: Starting an apply batch of log records to the database...
InnoDB: Apply batch completed
InnoDB: Started
mysqld: ready for connections
Если ваша база данных оказалась повреждена или произошел сбой диска, вам потре-
буется восстановить ее из резервной копии. В случае повреждения базы данных сначала
необходимо найти неповрежденную резервную копию. Затем, после восстановления ба-
зы данных из резервной копии, следует восстановить бинарные журналы.
В некоторых случаях при повреждении базы данных бывает достаточно подготовить
дамп, удалить и создать повторно одну или несколько поврежденных таблиц. Для про-
верки целостности таблиц используется SQL-оператор CHECK TABLE, хотя сам по себе он
не в состоянии обнаружить все возможные разновидности повреждений. Для проверки
целостности табличного пространства применяется innodb_tablespace_monitor.
В некоторых случаях видимые повреждения страниц базы данных возникают вслед-
ствие того, что в операционной системе оказывается поврежденным кэш файлов, при
этом данные на диске остаются незатронутыми. В таких ситуациях лучше всего попы-
таться перезапустить компьютер. При перезапуске можно будет устранить ошибки, ко-
торые потенциально могли бы повредить страницу базы данных.

9.9.1. Принудительное восстановление


Предположим, что у вас произошло повреждение страниц базы данных, и вы пришли
к выводу, что решить проблему можно с помощью дампа таблиц базы данных и коман-
ды SELECT INTO OUTFILE. Как правило, большая часть данных окажется неповрежденной
и корректной. Однако повреждение может привести к неправильному выполнению опе-
рации SELECT * FROM имя_ та блицы или фоновых операций InnoDB, либо даже к коррект-
ному выполнению восстановления InnoDB с повтором всех завершенных транзакций. В
версии MySQL 3.23.44 была введена переменная, которую можно использовать для за-
пуска механизма InnoDB; можно также запретить выполнение фоновых операций, что
9.9. Создание резервных копий и восстановление базы данных InnoDB 549

позволит выполнять дамп таблиц. Например, перед перезапуском сервера в разделе


[mysqld] файла опций можно добавить следующую строку:
[mysqld]
innodb_force_recovery =4
До MySQL 4.0 применялся следующий синтаксис:
[mysqld]
set-variable = innodb_force_recovery=4
Параметру innodb_force_recovery присваиваются положительные значения.
Большое значение сочетает все меры предосторожности меньших значений. Если вы
можете выполнить дамп таблиц, присвоив этому параметру значение менее 4, то в от-
дельных поврежденных страницах могут быть утрачены всего лишь некоторые дан-
ные. Если присвоить значение 6, то страницы базы данных останутся в прежнем со-
стоянии, что, в свою очередь, может привести к повреждению В-деревьев и других
структур базы данных.
• 1 (SRV_FORCE_IGNORE_CORRUPT). ПОЗВОЛИТЬ серверу работать даже в случае обна-
ружения поврежденных страниц; попытаться пропустить выполнение команды
SELECT * FROM имя_таблицы для поврежденных записей индекса и страниц, что
поможет подготовить дамп таблиц.
• 2 (SRVFORCENOBACKGROUND). Предотвратить выполнение главного потока. Если
сбой произойдет во время выполнения очистки, она будет защищена.
• 3 (SRV_FORCE_NO_TRX_UNDO). He выполнять откат транзакций после восстанов-
ления.
• 4 (sRVFORCENOIBUFMERGE). Предотвратить выполнение операций слияния бу-
фера вставок. Если они могут привести к возникновению аварийной ситуации,
лучше всего не выполнять их; не выполнять вычисление статистики по таблице.
• 5 (SRV_FORCE_NO_UNDO_LOG_SCAN). He просматривать журналы отмены выполнен-
ных операций во время запуска базы данных: InnoDB будет трактовать незавер-
шенные транзакции как завершенные.
• б (SRV_FORCE_NO_LOG_RED0)- He регистрировать восстановление с повтором всех
завершенных транзакций.
Любое другое использование этих параметров в базе данных исключено. В качестве
меры безопасности InnoDB запрещает пользователям выполнять операции INSERT, UPDATE
и DELETE, когда параметру innodb_f orce_recovery присвоено значение больше нуля.
Начиная с версий MySQL 3.23.53 и 4.0.4, разрешается выполнение команд DROP и
CREATE над таблицами даже при принудительном восстановлении. Если вы уверены в
том, что определенная таблица стала причиной сбоя при выполнении отката, ее можно
удалить. Этот параметр можно использовать также и для останова неконтролируемого
отката, вызванного сбоем при массовом импортировании или выполнении ALTER TABLE.
Можно уничтожить процесс mysqld и присвоить параметру innodb_f orce_recovery зна-
чение 3, чтобы остановить работу базы данных без отката. Затем с помощью команды
DROP потребуется удалить таблицу, вызвавшую откат.
550 Глава 9. Механизм хранения InnoDB

9.9.2. Контрольные точки


В InnoDB реализован механизм установки контрольных точек, называемый "нечеткой
контрольной точкой" (fuzzy checkpoint). InnoDB сбрасывает измененные страницы базы
данных из буферного пула на диск небольшими частями. Сбрасывать содержимое бу-
ферного пула в одном большом пакете нет необходимости, поскольку это может привес-
ти к останову обработки SQL-операторов, выданных пользователями.
При восстановлении InnoDB производит поиск меток контрольных точек, записанных
в журнальных файлах. Известно, что все изменения базы данных, внесенные перед мет-
кой, уже представлены в дисковом образе базы данных. Затем InnoDB приступает к ска-
нированию файлов журналов от контрольной точки и вносит зарегистрированные изме-
нения в базу данных.
Регистрация в журналах в InnoDB осуществляется циклически. Все внесенные изме-
нения, после которых страницы базы данных в буфере становятся отличными от образа
на диске, должны быть доступны в журнальных файлах. Это необходимо для тех случа-
ев, когда InnoDB придется производить восстановление. Это означает, что когда меха-
низм InnoDB начинает повторно использовать файл журнала, он проверяет, содержат ли
образы страниц базы данных на диске изменения, зарегистрированные в журнале. Дру-
гими словами, необходимость поставить контрольную точку зачастую приводит к тому,
что InnoDB сбрасывает измененные страницы базы данных на диск.
Из сказанного выше становится понятно, почему при больших файлах журналов со-
кращается количество дисковых операций ввода-вывода в случае установки контроль-
ных точек. Иногда имеет смысл задавать общий размер файлов журналов таким, чтобы
он был равен буферному пулу или даже больше. Недостаток больших журнальных фай-
лов заключается в том, что восстановление после сбоя может длиться дольше, поскольку
базе данных приходится учитывать больше информации из журнала.

9.10. Перенос базы данных InnoDB


на другой компьютер
В среде Windows механизм хранения InnoDB всегда хранит имена баз данных и таб-
лиц в нижнем регистре. Чтобы перенести базу данных в двоичном формате из платфор-
мы Unix на платформу Windows или наоборот, необходимо, чтобы все имена были пред-
ставлены в нижнем регистре. В Unix это можно сделать следующим образом. Прежде
чем приступить к созданию баз данных и таблиц, в разделе [mysqld] файла опций
my. cnf добавьте следующую строку:
[mysqld]
set-variable = lower_case_table_names=l
В Windows опция lower_case_table_names по умолчанию имеет значение 1.
Как и файлы данных MylSAM, файлы данных и файлы журналов InnoDB на двоичном
уровне совместимы на всех платформах, если на компьютерах совпадает формат чисел с
плавающей запятой. Базу данных InnoDB можно перенести без особого труда, скопиро-
вав все связанные с ней файлы (список которых был приведен в разделе 9.9). Если ком-
пьютеры имеют различные форматы чисел с плавающей запятой, а типы данных FLOAT
или DOUBLE в ваших таблицах не используются, последовательность действий остается
прежней: нужно просто скопировать все файлы, связанные с базой данных. Если же на
9.11. Транзакционная модель InnoDB и блокирование 551

ваших машинах поддерживаются различные форматы, а в таблицах содержатся данные с


плавающей запятой, то чтобы перенести такие таблицы, необходимо сначала с помощью
mysqldump подготовить дамп таблиц на одной машине, а затем перенести файлы дампа
на другую машину.
Чтобы увеличить скорость обработки, можно отключить режим автоматической фик-
сации транзакций во время импорта данных в базу, при условии, что ваше табличное
пространство способно принять большой сегмент отката, который будет сгенерирован
большой транзакцией импорта. Фиксацию нужно будет выполнить только после импор-
та всей таблицы или ее сегмента.

9.11. Транзакционная модель InnoDB


и блокирование
Транзакционная модель InnoDB призвана комбинировать лучшие возможности мно-
говариантных баз данных и традиционного двухфазного блокирования. Механизм
InnoDB устанавливает блокировки на уровне строки и по умолчанию выполняет запросы
в форме согласованных считываний без блокировок, как это реализовано в Oracle. Хра-
нение таблицы блокировок в InnoDB организовано настолько экономно, что отпадает
необходимость в расширении блокировки: обычно нескольким пользователям одновре-
менно разрешается блокировать каждую строку или любой произвольный набор строк в
базе данных, не занимая всю память, доступную для InnoDB.

9.11.1. InnoDB и режим автоматической


фиксации AUTOCOMMIT
В InnoDB все действия пользователей выполняются внутри транзакции. Если режим
автоматической фиксации включен, то каждый SQL-оператор формирует свою собст-
венную транзакцию. Новое соединение в MySQL всегда начинается в режиме автомати-
ческой фиксации.
Если режим автоматической фиксации отключен с помощью оператора SET
AUTOCOMMIT=0, можно считать, что у пользователя всегда имеется открытая транзакция.
SQL-операторы COMMIT и ROLLBACK завершают выполнение текущей транзакции и начи-
нают новую. Оба оператора снимают все блокировки InnoDB, которые были приняты во
время выполнения текущей транзакции. Если использовать оператор COMMIT, то все из-
менения, выполненные в период текущей транзакции, будут сохранены и видимы для
других пользователей. Если применить оператор ROLLBACK, все изменения, произведен-
ные в период текущей транзакции, будут отменены.
Если соединение было установлено при включенном режиме автоматической фикса-
ции, пользователь может продолжить выполнение транзакции с несколькими операто-
рами посредством одного из операторов START TRANSACTION и BEGIN и завершить ее с
ПОМОЩЬЮ COMMIT ИЛИ ROLLBACK.

9.11.2. InnoDB и уровень изоляции транзакций


(TRANSACTION ISOLATION LEVEL)
В терминах описания уровней изоляции транзакций SQL: 1992 в InnoDB по умолча-
нию применяется повторяющееся чтение (REPEATABLE READ). Начиная с версии MySQL
552 Глава 9. Механизм хранения InnoDB

4.0.5, в InnoDB предлагается четыре различных уровня изоляции транзакций, описанные


в стандарте SQL. С помощью опции —transaction-isolation командной строки или в
файлах опций можно установить уровень изоляции, который будет использоваться по
умолчанию для всех соединений. Например, в разделе [raysqld] файла my.cnf этот пара-
метр можно установить следующим образом:
[mysqld]
transaction-isolation = {READ-UNCOMMITTED | READ-COMMITTED
| REPEATABLE-READ | SERIALIZABLE}
Пользователь может изменить уровень изоляции транзакций для отдельно взятого
сеанса или нового соединения следующим образом:
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL
{READ UNCOMMITTED | READ COMMITTED
I REPEATABLE READ | SERIALIZABLE}
Обратите внимание на то, что в опции --transaction-isolation имена уровней изо-
ляции пишутся через дефис, а в операторе SET TRANSACTION - нет.
Поведение по умолчанию определяет выбор уровня изоляции для следующей (а не
для выполняющейся) транзакции. Если указать ключевое слово GLOBAL, то указанное
выше выражение будет определять глобальный уровень изоляции, принимаемый по
умолчанию для всех новых соединений (но не для существующих соединений). Для это-
го вам понадобится привилегия суперпользователя (SUPER). Если указать ключевое слово
SESSION, то это выражение будет определять уровень изоляции, принимаемый по умол-
чанию для всех транзакций, которые будут выполняться во время данного соединения.
Каждый клиент может изменить уровень изоляции для своего сеанса (даже внутри
самой транзакции) или уровень изоляции для следующей транзакции.
До выхода версии MySQL 3.23.50 оператор SET TRANSACTION не работал с таблицами
InnoDB. До версии 4.0.5 были доступны только операторы REPEATABLE READ и
SERIALIZABLE.
Запросить глобальные и сеансовые уровни изоляции транзакций можно с помощью
следующих операторов:
SELECT @@global.tx_isolation;
SELECT @@tx_isolation;
В блокировке уровня строки InnoDB использует так называемую "блокировку сле-
дующего ключа" (next-key locking). Она означает, что помимо индексных записей InnoDB
может блокировать также и "интервал" (gap) перед индексной записью, что позволяет
блокировать вставки другими пользователями непосредственно перед индексной запи-
сью. Блокирование следующего ключа означает блокирование индексной записи и ин-
тервала перед ней. Блокирование интервала означает блокирование только интервала
перед некоторыми индексными записями.
Далее следует подробное описание каждого уровня изоляции в InnoDB:
• READ UNCOMMITTED. Операторы SELECT выполняются без блокирования с возмож-
ным использованием более ранних версий записи. Таким образом, используя уро-
вень изоляции, такие считывания не являются "согласованными" (другое назва-
ние - "недействительные чтения"). В остальных случаях этот уровень работает
так же, как и READ COMMITTED.
9.11. Транзакционная модель InnoDB и блокирование 553

• READ COMMITTED. Подобен уровню изоляции в Oracle. Все операторы SELECT...


FOR UPDATE и SELECT.. .LOCK IN SHARE MODE блокируют только индексные записи,
оставляя нетронутыми интервалы перед ними. Таким образом, они позволяют
свободно добавлять новые записи после заблокированных записей. Операторы
UPDATE и DELETE, которые используют уникальный индекс и уникальные условия
поиска, блокируют только обнаруженную индексную запись, оставляя нетрону-
тым интервал перед ней. В операторах диапазонного типа UPDATE и DELETE меха-
низм InnoDB должен установить блокировку следующего ключа или блокировку
интервалов и заблокировать вставки другими пользователями в интервалах, попа-
дающих в диапазон. Это необходимо для того, чтобы гарантировать успешное
выполнение репликации и восстановления в MySQL, заблокировав так называе-
мые "фантомные строки" (phantom row).
Согласованные чтения работают так же, как и в Oracle: каждое согласованное
чтение, даже внутри одной и той же транзакции, устанавливает и читает свой соб-
ственный последний снимок. См. раздел 9.11.3.
• REPEATABLE READ. Этот уровень изоляции используется в InnoDB по умолчанию.
Операторы SELECT... FOR UPDATE, SELECT. . .LOCK IN SHARE MODE, UPDATE И DELETE,
которые используют уникальные индексы и уникальное условие поиска, блоки-
руют только обнаруженную индексную запись, оставляя нетронутым интервал
перед ней. При остальных условиях поиска в этих операциях используется блоки-
ровка следующего ключа, блокировка диапазона индексов, сканированных по-
средством блокировки следующего ключа или интервалов, и блокировка новых
вставок другими пользователями.
В согласованных чтениях есть важное отличие от предыдущего уровня изоляции:
на этом уровне все согласованные чтения внутри одной и той же транзакции чи-
тают тот же снимок, который был сделан при первом чтении. А это значит, что
если внутри одной и той же транзакции вы выполните несколько простых выбо-
рок (с помощью оператора SELECT), эти выборки будут соответствовать друг дру-
гу. См. раздел 9.11.3.
• SERIALIZABLE. Этот уровень подобен уровню REPEATABLE READ, однако все про-
стые операторы SELECT просто преобразуются в SELECT... LOCK IN SHARE MODE.

9.11.3. Согласованное чтение без блокировки


Согласованное чтение означает, что InnoDB использует многовариантные таблицы
для предоставления запросу мгновенного снимка базы данных на конкретный момент
времени. Запросу будут доступны лишь те изменения, которые были произведены тран-
закциями, зафиксированными до этого момента времени, и недоступны изменения, вно-
симые незафиксированными или выполненными позже транзакциями. Исключение мо-
гут составить лишь те изменения, которые были произведены транзакцией, сформиро-
вавшей текущий запрос.
Если вы используете уровень изоляции REPEATABLE READ, принятый по умолчанию,
то все согласованные чтения из одной транзакции будут считывать мгновенный снимок,
полученный при первом таком чтении в текущей транзакции. Можно получить и более
свежую копию для своих запросов - для этого потребуется зафиксировать текущую
транзакцию и выдать новые запросы.
554 Глава 9. Механизм хранения InnoDB

Режим согласованного чтения используется по умолчанию. В этом режиме InnoDB


выполняет обработку операторов SELECT при уровнях изоляции READ COMMITTED или
REPEATABLE READ. Во время согласованного чтения не устанавливаются блокировки на
таблицы, к которым обращается запрос, и поэтому остальные пользователи могут вно-
сить изменения в эти таблицы одновременно с согласованным чтением таблиц.

9.11.4. Чтения с блокировкой: SELECT... FOR UPDATE


и SELECT... LOCK IN SHARE MODE
В некоторых ситуациях согласованное чтение не подходит для решения данной зада-
чи. Предположим, что вам необходимо добавить новую строку в таблицу child, предва-
рительно убедившись, что в таблице parent для нее существует родительская строка.
Далее следует пример, демонстрирующий способ реализации ссылочной целостности в
коде вашего приложения.
Допустим, что для чтения таблицы parent вы используете согласованное чтение, и
что в этой таблице действительно была обнаружена родительская строка. Сможете ли вы
сейчас добавить дочернюю строку в таблицу child, не беспокоясь о негативных послед-
ствиях? Нет, потому что в это время другой пользователь мог без вашего ведома удалить
родительскую строку из таблицы parent.
В подобных ситуациях необходимо произвести извлечение (SELECT) в режиме блоки-
ровки, ИСПОЛЬЗуя LOCK IN SHARE MODE:
SELECT * FROM PARENT WHERE NAME = ' J o n e s ' LOCK IN SHARE MODE;

При выполнении чтения в режиме совместного использования будут считываться са-


мые новые доступные данные и будут заблокированы читаемые строки в режиме совме-
стного использования. При блокировке в режиме совместного использования другие
пользователи не смогут обновить или удалить читаемую строку. Кроме этого, если эти
новые данные принадлежат еще не зафиксированной транзакции, будет ожидаться ее
завершение. После того как указанный выше запрос вернет родительскую строку
'Jones', мы сможем безопасно добавить дочернюю строку в таблицу child и зафикси-
ровать транзакцию.
Рассмотрим еще один пример. Пусть имеется поле целочисленного счетчика в табли-
це child_codes, которое применяется для присвоения уникального идентификатора ка-
ждой дочерней записи, добавляемой к таблице child. Очевидно, что для получения те-
кущего значения счетчика использовать согласованное чтение или чтение в режиме
совместного доступа нельзя, поскольку два пользователя базы данных могут получить
одно и то же значение счетчика; кроме того, у обоих пользователей возникнет ошибка
дублированного ключа, если они попытаются добавить в таблицу дочерние записи с
одинаковым идентификатором.
Применять LOCK IN SHARE MODE нецелесообразно: если два пользователя одновре-
менно попытаются получить значение счетчика, то, как минимум, у одного пользователя
произойдет сбой при попытке обновить счетчик.
На этот случай наиболее оптимальными представляются два способа чтения и увели-
чения значения счетчика: (1) нужно обновить значение счетчика, увеличив его на 1, и
после этого прочитать его, или (2) сначала прочитать счетчик в режиме блокировки FOR
UPDATE, а затем увеличить его значение. Второй способ можно реализовать следующим
образом:
9.11. Транзакционная модель InnoDB и блокирование 555

SELECT counter_field FROM child_codes FOR UPDATE;


UPDATE child_codes SET counter_field = counter_field + 1;
Оператор SELECT...FOR UPDATE производит чтение последних доступных данных,
блокируя по отдельности каждую считываемую строку. Он устанавливает блокировки на
строки точно так же, как и при поиске с помощью SQL-оператора UPDATE.
Заметьте, что приведенный пример касается работы оператора SELECT.. .FOR UPDATE.
В MySQL специфическую задачу генерирования уникального идентификатора на самом
деле можно выполнить с помощью всего лишь одного обращения к таблице:
UPDATE child_codes SET counter_field = LAST_INSERT_ID(counter_field + DE-
SELECT LAST_INSERT_ID();
Оператор SELECT просто получает информацию об идентификаторе (специфическую
информацию для данного соединения). Он не обращается ни к одной таблице.

9.11.5. Блокировка следующего ключа:


устранение "проблемы с фантомом"
При блокировке на уровне строк в InnoDB используется алгоритм, называемый "бло-
кировкой следующего ключа" (next-key locking). Блокировка на уровне строк осуществ-
ляется таким образом, что во время поиска или сканирования индекса таблицы устанав-
ливается совместно используемая или эксклюзивная блокировка обрабатываемых запи-
сей индексов. Поэтому блокировки на уровне строк на самом деле являются
блокировками записей индексов.
Блокировки, которые в InnoDB устанавливаются на индексные записи, распространя-
ются также и на интервал перед данной индексной записью. Если пользователь устано-
вил совместно используемую или эксклюзивную блокировку записи R в индексе, то дру-
гой пользователь не сможет вставить новую индексную запись непосредственно перед
записью R в порядке следования индексов. Такая блокировка интервалов реализуется для
того, чтобы не допустить возникновения так называемой "проблемы с фантомом"
("phantom problem"). Предположим, что в таблице child необходимо прочитать и забло-
кировать все дочерние записи с идентификатором, значение которого превышает 100, и
затем в выбранных строках обновить некоторые поля:
SELECT * FROM c h i l d WHERE i d > 100 FOR UPDATE;

Допустим, что по столбцу id создан индекс. При запросе будет произведено скани-
рование этого индекса, начиная с первой записи, в которой id больше 100. Далее, если
установленные на записях индекса блокировки не заблокируют вставки в интервалы, то
за это время в таблицу может быть вставлена новая строка. Если сейчас выполнить эту
же команду SELECT в этой же транзакции, то после выполнения запроса вы сможете уви-
деть новую строку. Это противоречит принципу изоляции транзакции: транзакция
должна выполняться таким образом, чтобы считываемые ею данные не изменялись во
время выполнения транзакции. Если набор строк считать элементом данных, то новый
дочерняя "фантомная запись" нарушит этот принцип изоляции.
Когда InnoDB сканирует индекс, она может также заблокировать интервалы после по-
следней записи в индексе. Именно это и было продемонстрировано в предыдущем при-
мере: блокировка, установленная InnoDB, запрещает вставку в таблицу, если id будет
больше 100.
556 Глава 9. Механизм хранения InnoDB

Блокировку следующего ключа можно использовать для того, чтобы проверить уни-
кальность значений в своем приложении. Если данные считываются в режиме совмест-
ного доступа, и отсутствует дубликат строки, которую необходимо вставить, то можно
безопасно вставлять свою строку и быть уверенным, что благодаря блокировке следую-
щего ключа, установленной на предшествующей строке во время чтения, будет запре-
щена вставка дублированной строки. Таким образом, блокировка следующего ключа
позволяет "заблокировать" отсутствие чего-либо в таблице.

9.11.6. Пример работы согласованного чтения в InnoDB


Предположим, что вы используете уровень изоляции, установленный по умолча-
нию - REPEATABLE READ. При выполнении согласованного чтения (то есть обычного опе-
ратора SELECT) InnoDB определяет для транзакции момент времени, когда запросу будет
предоставлена информация из базы данных. Поэтому если во время транзакции будет
удалена строка и это изменение будет зафиксировано после указанного момента време-
ни, вы не увидите, что строка была удалена. Это справедливо также для вставок и об-
новлений.
Чтобы такой момент времени сдвинуть как можно дальше, нужно зафиксировать
транзакцию и выполнить новый оператор SELECT.
Этот прием называется многовариантным контролем совпадений (multi-versioned
concurrency control).
User A User В
SET AUTOCOMMIT=0; SET AUTOCOMMIT=0;
time
| SELECT * FROM t ;
I empty s e t
| INSERT INTO t VALUES ( 1 , 2);
I
v SELECT * FROM t ;
empty s e t
COMMIT;
SELECT * FROM t ;
empty s e t
COMMIT;
SELECT * FROM t ;

1 row in set
В этом примере пользователь А увидит строку, вставленную пользователем В, только
после того, как пользователь В зафиксирует вставку, а пользователь А зафиксирует свою
собственную транзакцию, чтобы момент времени сдвинулся на позицию после фикса-
ции, которую выполнил пользователь В.
Чтобы увидеть "наиболее актуальное" состояние базы данных, необходимо восполь-
зоваться чтением с блокировкой:
SELECT * FROM t LOCK IN SHARE MODE;
9.11. Транзакционная модель InnoDB и блокирование 557

9.11.7. Блокировка, устанавливаемая различными


SQL-операторами в InnoDB
Чтения с блокировкой, команды UPDATE или DELETE устанавливают блокировки запи-
сей на каждой индексной записи, сканируемой в процессе выполнения SQL-запроса. Не
имеет значения, присутствуют ли в запросе условия WHERE, которые исключат строку из
полученного набора по запросу. InnoDB не запоминает точное условие WHERE, а знает
только о том, какие индексные диапазоны были отсканированы. Блокировки записей
обычно являются блокировками следующего ключа, которые также блокируют вставки в
интервал непосредственно перед записью.
Если блокировки являются эксклюзивными, InnoDB всегда будет получать также и
кластеризованную индексную запись, устанавливая на ней блокировку.
Если индексы, подходящие для вашего запроса, отсутствуют, и MySQL пришлось
сканировать всю таблицу, чтобы обработать запрос, то каждая строка таблицы будет
заблокированной. В свою очередь, это приведет к блокировке всех вставок в таблицу,
выполняемых другими пользователями. Здесь важно создать правильно подобранные
индексы, которые позволят сократить время поиска за счет сканирования меньшего ко-
личества строк.
• SELECT... FROM осуществляет согласованное чтение снимка базы данных без бло-
кировок, пока уровнем изоляции транзакции не является SERIALIZABLE. Для уров-
ня SERIALIZABLE будет установлены совместно используемые блокировки сле-
дующего ключа на все считываемые индексные записи.
• SELECT.. .FROM.. .LOCK IN SHARE MODE устанавливает совместно используемые
блокировки следующего ключа на все считываемые индексные записи.
• SELECT.. .FROM.. .FOR UPDATE устанавливает эксклюзивную блокировку следую-
щего ключа на все считываемые индексные записи.
• INSERT INTO.. .VALUES (...) устанавливает эксклюзивную блокировку на встав-
ленную строку. Заметьте, что эта блокировка не является блокировкой следующего
ключа и не запрещает вставку записей другими пользователями в интервале перед
вставленной строкой. Если произойдет ошибка дублирования ключа, оператор ус-
тановит блокировку совместного использования на запись дублированного индекса.
• Во время инициализации предварительно описанного столбца AUTO_INCRESEMENT в
таблице механизм InnoDB устанавливает эксклюзивную блокировку в конце ин-
декса, связанного со столбцом AUTOINCREMENT. Для доступа к счетчику с автома-
тическим приращением InnoDB использует специальный режим блокировки таб-
лицы AUTO-INC, при котором блокировка продолжается только до завершения вы-
полнения текущего SQL-оператора, а не до завершения выполнения всей
транзакции. См. раздел 9.11.1.
До выхода версии MySQL 3.23.50 команда SHOW TABLE STATUS, выполненная над
таблицей со столбцом AUTOINCRESEMENT, устанавливала эксклюзивную блоки-
ровку на уровне строк до конца индекса AUTO_INCREMENT. Это означает также,
что команда SHOW TABLE STATUS может вызвать взаимную блокировку транзак-
ций, приводя в замешательство пользователей. Начиная с версии MySQL
3.23.50, InnoDB выбирает значение предварительно инициализированного столбца
AUTO_INCRESEMENT, не устанавливая какие-либо блокировки.
558 Глава 9. Механизм хранения InnoDB

• INSERT INTO T SELECT... FROM S WHERE... устанавливает эксклюзивную (не сле-


дующего ключа) блокировку на каждую вставляемую в таблицу Т строку. Осуще-
ствляет поиск в таблице S в виде согласованного чтения, однако если будет вклю-
чен режим бинарной регистрации, то в таблице S будут установлены совместно
используемые блокировки следующего ключа. В последнем случае InnoDB должна
устанавливать блокировки, поскольку при восстановлении с повтором всех за-
вершенных транзакций из резервной копии каждый SQL-оператор потребуется
выполнить точно так таким же образом, как и изначально.
• CREATE TABLE... SELECT... выполняет SELECT в виде согласованного чтения или с
блокировками совместного использования, как в предыдущем пункте.
• REPLACE выполняется так же, как и вставка, при отсутствии конфликтов уникаль-
ных ключей. В противном случае на строке, подлежащей обновлению, будет ус-
тановлена эксклюзивная блокировка следующего ключа.
• UPDATE.. .WHERE... устанавливает эксклюзивную блокировку следующего ключа
на каждой записи, обнаруженной в процессе поиска.
• DELETE FROM.. .WHERE... устанавливает эксклюзивную блокировку следующего
ключа на каждой записи, обнаруженной во время поиска.
• Если для таблицы определены ограничения FOREIGN KEY, то для любой вставки,
обновления или удаления, для которых потребуется проверка условий ограниче-
ния, будет установлена совместная блокировка на уровне записей, которые про-
сматриваются во время проверки ограничения. В InnoDB эти блокировки устанав-
ливаются также при нарушении ограничения.
• LOCK TABLES... устанавливает блокировку таблицы. Эта блокировка производит-
ся кодом на уровне MySQL. Механизм автоматического обнаружения взаимных
блокировок InnoDB не позволяет обнаруживать взаимные блокировки, в которых
участвуют подобные блокировки таблиц. См. раздел 9.11.9.
Кроме того, поскольку MySQL известно о блокировке на уровне строки, можно
установить блокировку таблицы, в которой на данный момент какой-нибудь дру-
гой пользователь заблокировал строки. Это, однако, никоим образом не влияет на
целостность транзакции. См. раздел 9.17.

9.11.8. В каких случаях MySQL явно выполняет


фиксацию или откат транзакции
По умолчанию MySQL устанавливает соединение с каждым клиентом в режиме ав-
томатической фиксации. Если этот режим включен, MySQL выполняет фиксацию после
каждого SQL-оператора, если в результате его выполнения не была возвращена ошибка.
Если режим автоматической фиксации выключен, и соединение закрывается без вы-
полнения явной фиксации вашей транзакции, MySQL выполнит откат транзакции.
Если SQL-оператор возвращает ошибку, поведение фиксации/отката будет зависеть
от возникшей ошибки. См. раздел 9.16.
Следующие SQL-операторы инициируют явную фиксацию текущей транзакции в
MySQL:
9.11. Транзакционная модель InnoDB и блокирование 559

• ALTER TABLE, BEGIN, CREATE INDEX, DROP DATABASE, DROP INDEX, DROP TABLE,
LOAD MASTER DATA, LOCK TABLES, RENAME TABLE, SET AUTOCOMMIT=1, START
TRANSACTION, TRUNCATE, UNLOCK TABLES.
• CREATE TABLES (фиксация производится только в том случае, если в версиях
MySQL, предшествующих 4.0.13, используется бинарная регистрация).
• Оператор CREATE TABLE в InnoDB обрабатывается как одна транзакция. Это озна-
чает, что команда ROLLBACK, инициированная пользователем, не приведет к отмене
выполнения операторов CREATE TABLE, выданных пользователем во время данной
транзакции.

9.11.9. Обнаружение взаимных блокировок и откат


Механизм InnoDB автоматически обнаруживает взаимную блокировку транзакций и с
целью предотвращения подобного рода блокировок выполняет откат одной или не-
скольких транзакций. Начиная с версии MySQL 4.0.5, InnoDB пытается выбирать для
отката небольшие транзакции. Размер транзакции определяется количеством строк, ко-
торые должны быть вставлены, обновлены или удалены. До версии MySQL 4.0.5 меха-
низм InnoDB производил откат той транзакции, чей запрос на блокировку был послед-
ним, вызвавшим взаимную блокировку, то есть, приводил к возникновению замкнутого
цикла в графике ожиданий транзакций.
Механизм InnoDB не способен обнаруживать взаимные блокировки, в которых блоки-
ровка таблицы была осуществлена с помощью MySQL-оператора LOCK TABLES или другим
механизмом хранения, отличным от InnoDB. В ситуациях подобного рода необходимо при-
своить определенное значение системной переменной innodb_lock_wait_timeout.
Когда InnoDB выполняет откат транзакции, снимаются все блокировки транзакции.
Тем не менее, если в результате ошибки произошел откат только одного SQL-оператора,
некоторые блокировки, установленные SQL-оператором, могут сохраниться. Это проис-
ходит потому, что InnoDB хранит блокировку строк в формате, который впоследствии не
позволяет определить, каким конкретно SQL-оператором устанавливалась блокировка.

9.11.10. Как справляться с взаимными блокировками


Взаимные блокировки являются классической проблемой транзакционных баз дан-
ных. Они не опасны до тех пор, пока не начинают возникать настолько часто, что вы
вообще оказываетесь не в состоянии запустить некоторые транзакции. Обычно вы
должны разрабатывать свои приложения так, чтобы они всегда были подготовлены к
повторному выполнению транзакции в случае отката, вызванного возникновением вза-
имной блокировки.
InnoDB использует автоматическую блокировку на уровне строки. Столкнуться с вза-
имной блокировкой вы можете даже тогда, когда в транзакциях выполнятся вставка или
удаление одной строки. Это происходит из-за того, что в действительности эти операции
не являются атомарными; они автоматически блокируют индексные записи добавляе-
мых или удаляемых строк (возможно, даже несколько записей).
Справиться с взаимными блокировками или снизить вероятность их появления мож-
но следующими способами:
• Чтобы установить причину возникновения последней взаимной блокировки, ис-
пользуйте команду SHOW INNODB STATUS. Вы сможете соответствующим образом
560 Глава 9. Механизм хранения InnoDB

настроить свое приложение и избежать возникновения взаимных блокировок.


Этот способ можно реализовать в версиях MySQL 3.23.52 и MySQL 4.0.3, в зави-
симости от линейки MySQL.
• Всегда будьте готовы к повторному выполнению транзакции, если ее сбой был
вызван взаимной блокировкой. Взаимные блокировки не являются опасным явле-
нием, поэтому попытайтесь выполнить транзакцию снова.
• Чаще фиксируйте свои транзакции. Небольшие транзакции менее часто становят-
ся причиной возникновения конфликтов.
• Если вы используете чтение с блокировкой (SELECT.. .FOR UPDATE или .. .LOCK IN
SHARE MODE), попытайтесь использовать более низкий уровень изоляции, напри-
мер READ COMMITTED.
• Старайтесь придерживаться фиксированного порядка обращения к своим табли-
цам и строкам, что позволит формировать согласованную очередность выполне-
ния транзакций, не давая повода для возникновения взаимных блокировок.
• Старайтесь использовать в своих таблицах тщательно подобранные индексы. То-
гда ваши запросы будут сканировать меньшее количество индексных записей и,
соответственно, будет установлено меньшее количество блокировок. Используйте
EXPLAIN SELECT, чтобы узнать, какие индексы сервер MySQL считает наиболее
подходящими для выполнения ваших запросов.
• Используйте как можно меньшее количество блокировок: если вы можете допус-
тить, чтобы команда SELECT вернула данные из старого снимка, не добавляйте к
ней конструкцию FOR UPDATE или LOCK IN SHARE MODE. Используйте уровень изо-
ляции READ COMMITTED, который больше всего подходит для данной ситуации -
при каждом согласованном чтении внутри одной и той же транзакции будет про-
читан свой собственный актуальный снимок.
• Если ничего не помогло, выполните последовательно свои транзакции с блоки-
ровкой на уровне таблицы. Например, если вам нужно записать таблицу t i n про-
читать таблицу t2, можете выдать следующие операторы:
LOCK TABLES t l WRITE, t2 READ, . . . ;
[do something with tables t l and t2 h e r e ] ;
UNLOCK TABLES;
Блокировки на уровне таблиц выстраивают ваши транзакции в очередь, что по-
зволяет избежать возникновения взаимных блокировок. Заметьте, что LOCK
TABLES неявно начинает транзакцию, подобно оператору BEGIN, a UNLOCK TABLES
неявно завершает ее, подобно COMMIT.
• Еще один способ организации последовательного выполнения транзакций заклю-
чается в создании вспомогательной "семафорной" таблицы, содержащей одну
строку. Каждая транзакция будет обновлять эту строку, прежде чем обращаться к
другой таблице. В этом случае все транзакции выполняются последовательно.
Обратите внимание на то, что таким же образом в настоящий момент работает и
алгоритм обнаружения взаимных блокировок, поскольку последовательная бло-
кировка представляет собой блокировку на уровне строки. Для устранения взаим-
ных блокировок на уровне таблицы в MySQL необходимо использовать метод
тайм-аута.
9.12. Советы по настройке производительности InnoDB 561

9.12. Советы по настройке


производительности InnoDB
• Если инструмент top в Unix или Task Manager (Диспетчер задач) в Windows
показывают, что процент рабочей нагрузки процессора меньше 70%, это значит,
что рабочая нагрузка связана, в основном, с обращениями к диску. Вероятно, вы
слишком часто фиксируете транзакции или слишком мал размер вашего буферно-
го пула. В этом случае можно увеличить размер буферного пула, но не более чем
до 80% от физической памяти.
• За одну транзакцию следует вносить несколько изменений. Механизм InnoDB дол-
жен сбрасывать журнал на диск после каждой фиксации транзакции, если эта тран-
закция внесла изменения в базу данных. Поскольку скорость вращения диска обыч-
но не превышает 167 оборотов в секунду, то количество фиксаций ограничено 167
фиксациями в секунду, если, конечно, диск не "обманывает" операционную систему.
• Если вы можете позволить себе терять последние зафиксированные транзакции,
тогда в файле my.cnf присвойте опции innodb_flush_log_at_trx_commit нулевое
значение. В любом случае, каждую секунду InnoDB будет пытаться сбросить жур-
нал, причем положительный результат этой операции не гарантируется.
• Увеличьте размеры журнальных файлов, пусть даже до размера буферного пула.
Когда механизм InnoDB заполняет файлы журналов, он должен сохранять изме-
ненное содержимое буферного пула на диске в контрольной точке. Имейте в виду,
что при работе с журналами небольших размеров может быть вызвано множество
ненужных записей на диск, а для больших журналов понадобится большее время
на восстановление после сбоя.
• Можно увеличить размер буфера журнала, например до 8 Мбайт.
• Вместо CHAR в качестве типа столбца используйте VARCHAR, если вы сохраняете
строки разной длины или если столбец содержит нулевые значения. Для хранения
данных столбец CHAR всегда занимает N байт, даже если строка короче или ее зна-
чением является NULL. Таблицы меньшего размера более всего подходят для бу-
ферного пула и сокращают количество дисковых операций ввода-вывода.
• (Актуально для версии MySQL 3.23.39 и выше.) В некоторых версиях операцион-
ных систем Linux и Unix запись файлов на диск с помощью команды f datasync и
других подобных методов выполняется на удивление медленно. По умолчанию в
InnoDB используется функция fdatasync. Если скорость записи в базу данных яв-
ляется достаточно низкой, в файле my.cnf можно попробовать присвоить опции
innodb_f lushjnethod значение O_DSYNC, хотя во многих механизмах это не приво-
дит к увеличению производительности.
• При импорте данных в InnoDB необходимо, чтобы в MySQL не был включен ре-
жим автоматической фиксации, поскольку для каждой вставки потребуется сбра-
сывать журналы на диск. Чтобы отключить режим автоматической фиксации во
время выполнения операции импортирования, поместите блок импортирования
между операторами SET AUTOCOMMIT и COMMIT:
SET AUTOCOMMIT=0;
/* SQL-операторы импортирования ... */
COMMIT;
562 Глава 9. Механизм хранения InnoDB

Если указать опцию —opt для mysqldump, вы получите файлы, которые будут дос-
таточно быстро импортироваться в таблицу InnoDB, даже если и не использовать
вышеуказанные операторы SET AUTOCOMMIT и COMMIT.
• Осторожно относитесь к большому количеству откатов массовых вставок: InnoDB
использует буфер вставок для того, чтобы сократить количество дисковых опера-
ций ввода-вывода, однако для соответствующего отката транзакции подобный
механизм не предусмотрен. Ограниченный физическими параметрами диска откат
может занять в 30 раз больше времени, чем вставка. Удаление процесса базы дан-
ных не поможет, поскольку после запуска базы данных снова начнется откат. Во
избежание подобного отката можно увеличить размер буферного пула настолько,
чтобы скорость выполнения отката зависела только от производительности цен-
трального процессора, либо предусмотреть для этого специальную процедуру.
См. раздел 9.9.1.
• Следует также осторожно относиться к операциям со значительными объемами
данных, которые зависят от производительности диска. Чтобы очистить таблицу,
применяйте операторы DROP TABLE или TRUNCATE (начиная с версии MySQL 4.0 и
выше), но не DELETE FROM имя_таблицы.
• Если вам нужно вставить большое количество строк, используйте синтаксис опе-
ратора INSERT с несколькими строками, что позволит сократить нагрузку на связь
между клиентом и сервером:
INSERT INTO имя_таблицы VALUES (1,2), (5,5), ...;
Этот совет подходит для вставок в таблицы любого типа, а не только для InnoDB.
• Если у вас имеются ограничения UNIQUE для вторичных ключей, то, начиная с
версий MySQL 3.23.52 и MySQL 4.0.3, можно ускорить импортирование таблиц,
если отключить на время проверки на уникальность:
SET UNIQUE_CHECKS=O;
При работе с крупными таблицами можно будет существенно сократить количе-
ство дисковых операций ввода-вывода, поскольку InnoDB сможет использовать
свой буфер вставки для групповой регистрации записей вторичных индексов.
• Если в ваших таблицах имеются ограничения внешнего ключа FOREIGN KEY, то,
начиная с версии MySQL 3.23.52 и MySQL 4.0.3, вы можете увеличить скорость
выполнения вставок в таблицу, отключив на время проверку внешних ключей:
SET FOREIGN_KEY_CHECKS=0;

Для больших таблиц это позволит сократить количество дисковых операций вво-
да-вывода.
• Если вы часто обращаетесь к редко обновляемым таблицам, используйте кэш
запросов, доступный в MySQL 4.0:
[mysqld]
query_cache_type = ON
query_cache__size = 10M
В MySQL 4.0 кэш запросов доступен только для режима автоматической фикса-
ции. В версии MySQL 4.1.1 это ограничение было снято.
9.12. Советы по настройке производительности InnoDB 563

9.12.1. SHOW INNODB STATUS и мониторы InnoDB


Начиная с версии MySQL 3.23.41, в состав InnoDB входят мониторы InnoDB, которые
выводят информацию о внутреннем состоянии InnoDB. Начиная с версий MySQL 3.23.52
и MySQL 4.0.3, с помощью SQL-onepaTopf SHOW INNODB STATUS можно передавать вы-
ходные данные стандартного монитора InnoDB вашему клиенту SQL. Эту информацию
полезно использовать для настройки производительности. Если вы пользуетесь интерак-
тивным клиентом mysql, то выходную информацию будет более удобно читать, если
заменить точку с запятой на \G:
mysql> SHOW INNODB STATUS\G
Другой способ использования мониторов InnoDB - позволить им непрерывно записы-
вать данные на стандартный вывод сервера mysqld. В этом случае информация не будет
пересылаться клиентам. В рабочем режиме мониторы InnoDB выводят данные примерно
каждые 15 секунд. Выходные данные сервера обычно направляются для регистрации в
журнал .err, который хранится в каталоге данных MySQL. Эти данные могут оказаться
полезными для настройки производительности. В среде Windows необходимо запустить
сервер из командной строки с опцией —console, если вы хотите направлять выходные
данные в окно, а не в журнал регистрации ошибок.
Монитор выводит следующую информацию:
• По блокировкам записей и таблиц, которые выполняются в каждой транзакции.
• По блокировкам, которые ожидают транзакции.
• По семафорам, которые ожидают потоки.
• По файлам, которые ожидают ответ на запросы ввода-вывода.
• По статистике буферного пула.
• По активности буферов удаления и вставок в основном потоке InnoDB.
Чтобы стандартный монитор InnoDB выводил информацию в стандартный вывод
mysqld, применяйте следующий SQL-оператор:
CREATE TABLE innodbjnonitor(a INT) TYPE=InnoDB;
Остановить монитор можно с помощью такого оператора:
DROP TABLE innodbjnonitor;
Синтаксис оператора CREATE TABLE предназначен только для передачи команды в ме-
ханизм InnoDB через синтаксический анализатор SQL: здесь играет роль только имя таб-
лицы innodbjnonitor и таблица InnoDB. Для монитора InnoDB структура таблицы значе-
ния не имеет. Если вы останавливаете функционирование сервера во время работы мо-
нитора и хотите запустить монитор повторно, вам придется сначала удалить таблицу, и
уже затем выдать оператор CREATE TABLE для запуска монитора. В следующей версии
этот синтаксис может быть изменен.
Подобным образом можно запустить innodb_lock_monitor, который подобен
innodbjnonitor, но выводит большой объем информации о блокировках. Отдельный мо-
нитор innodb_tablespace_monitor выводит перечень созданных сегментов файлов, суще-
ствующих в табличном пространстве, и проверяет правильность размещения структур
данных в табличном пространстве. В версии MySQL 3.23.44 появился монитор
innodb_table_monitor, который выводит содержимое внутреннего словаря данных InnoDB.
564 Глава 9. Механизм хранения InnoDB

Ниже представлен пример информации, выводимой монитором InnoDB:


mysql> SHOW INNODB STATUS\G
*************************** im r o w ***************************
Status:

030709 13:00:59 INNODB MONITOR OUTPUT

Per second averages calculated from the last 18 seconds

SEMAPHORES

OS WAIT ARRAY INFO: reservation count 413452, signal count 378357


--Thread 32782 has waited at btrOsea.c line 1477 for 0.00 seconds the
semaphore:
X-lock on RW-latch at 41a28668 created in file btrOsea.c line 135
a writer (thread id 32782) has reserved it in mode wait exclusive
number of readers 1, waiters flag 1
Last time read locked in file btrOsea.c line 731
Last time write locked in file btrOsea.c line 1347
Mutex spin waits 0, rounds 0, OS waits 0
RW-shared spins 108462, OS waits 37964; RW-excl spins 681824, OS waits 375485

LATEST FOREIGN KEY ERROR

030709 13:00:59 Transaction:


TRANSACTION 0 290328284, ACTIVE 0 sec, process no 3195, OS thread id 34831
inserting
15 lock struct (s), heap size 2496, undo log entries 9
MySQL thread id 25, query id 4668733 localhost heikki update
insert into ibtestlla (D, В, С) values (5, 'khDk' ,'khDk1)
Foreign key constraint fails for table test/ibtestlla:
v 4 4 4 4 V 4 S
CONSTRAINT 0_219242 FOREIGN KEY f A \ D ) REFERENCES 4btestllb ( A\ D )
ON DELETE CASCADE ON UPDATE CASCADE
Trying to add in child table, in index PRIMARY tuple:
0: len 4; hex 80000101; asc ;; 1: len 4; hex 80000005; asc ;; 2: len 4;
hex 6b68446b; asc khDk;; 3: len 6; hex 0000114e0edc; asc ...N..;; 4: len 7; hex
00000000c3e0a7; asc ;; 5: len 4; hex 6b68446b; asc khDk;;
But in parent table test/ibtestllb, in index PRIMARY,
the closest match we can find is record:
RECORD: info bits 0 0: len 4; hex 8000015b; asc ...[;; 1: len 4; hex 80000005; a
sc ;; 2: len 3; hex 6b6864; asc khd;; 3: len 6; hex 0000111ef3eb; asc
;; 4: len 7; hex 800001001e0084; asc ;; 5: len 3; hex 6b6864; asc khd;;

LATEST DETECTED DEADLOCK

030709 12:59:58
*** (1) TRANSACTION:
TRANSACTION 0 290252780, ACTIVE 1 sec, process no 3185, OS thread id 30733
inserting
LOCK WAIT 3 lock struct(s), heap size 320, undo log entries 146
9.12. Советы по настройке производительности InnoDB 565

MySQL thread id 21, query id 4553379 localhost heikki update


INSERT INTO alexl VALUES(86, 86,
1 f !
794,'aA35818','bb ,'c79166\'d4766t , el87358f
l l
,'g84586', h794',date_format( 2001-04-03 12:54:22','%Y-%m-%d %H:%i'),7
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 48310 n bits 568 table test/alexl index symbole
trx id 0 290252780 lock mode S waiting
Record lock, heap no 324 RECORD: info bits 0 0: len 7; hex 61613335383138; asc a
a35818;; 1:
*** (2) TRANSACTION:
TRANSACTION 0 290251546, ACTIVE 2 sec, process no 3190, OS thread id 32782
inserting
130 lock struct(s), heap size 11584, undo log entries 437
MySQL thread id 23, query id 4554396 localhost heikki update
REPLACE INTO alexl VALUES(NULL, 32, NULL,!aa3572','','c3572','d6012t', " ,
NULL,fh396', NULL, NULL, 7.31,7.31,7.31,200)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 48310 n bits 568 table test/alexl index symbole
trx id 0 290251546 lockjnode X locks rec but not gap
Record lock, heap no 324 RECORD: info bits 0 0: len 7; hex 61613335383138; asc a
a35818;; 1:
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 48310 n bits 568 table test/alexl index symbole
trx id 0 290251546 lockjnode X locks gap before rec insert intention waiting
Record lock, heap no 82 RECORD: info bits 0 0: len 7; hex 61613335373230; asc aa
35720;; 1:
*** WE ROLL BACK TRANSACTION (1)

TRANSACTIONS

Trx id counter 0 290328385


Purge done for trx's n:o < 0 290315608 undo n:o < 0 17
Total number of lock structs in row lock hash table 70
LIST OF TRANSACTIONS FOR EACH SESSION:
-—TRANSACTION 0 0, not started, process no 3491, OS thread id 42002
MySQL thread id 32, query id 4668737 localhost heikki
show innodb status
—TRANSACTION 0 290328384, ACTIVE 0 sec, process no 3205, OS thread id
38929 inserting
1 lock struct(s), heap size 320
MySQL thread id 29, query id 4668736 localhost heikki update
insert into speedc values (1519229,1,
'hgjhjgghggjgjgjgjgjggjgjgjgjgjgggjgjgjlhh
gghggggghhjhghgggggghjhghghghghghhhhghghghj hhj ghj ghj kghj ghj ghj ghj fhj fh
—TRANSACTION 0 290328383, ACTIVE 0 sec, process no 3180, OS thread id
28684 committing
1 lock struct(s), heap size 320, undo log entries 1
MySQL thread id 19, query id 4668734 localhost heikki update
insert into speedcm values (1603393,1,
'hgjhjgghggjgjgjgjgjggjgjgjgjgjgggjgjgjlh
hgghggggghhj hghgggggghj hghghghghghhhhghghghj hhj ghj ghj kghj ghj ghj ghj fhj f
566 Глава 9. Механизм хранения InnoDB

—-TRANSACTION 0 290328327, ACTIVE 0 sec, process no 3200, OS thread id


36880 starting index read
LOCK WAIT 2 lock struct(s), heap size 320
MySQL thread id 27, query id 4668644 localhost heikki Searching rows for update
update ibtestlla set В = 'kHdkkkk' where A = 89572
TRX HAS BEEN WAITING 0 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 65556 n bits 232 table test/ibtestlla index PRIM
ARY trx id 0 290328327 lockjnode X waiting
Record lock, heap no 1 RECORD: info bits 0 0: len 9; hex 73757072656d756d00; asc
supremum.;;

—TRANSACTION 0 290328284, ACTIVE 0 sec, process no 3195, OS thread id


34831 rollback of SQL statement
ROLLING BACK 14 lock struct(s), heap size 2496, undo log entries 9
MySQL thread id 25, query id 4668733 localhost heikki update
insert into ibtestlla (D, В, С) values (5, 'khDk' ,'khDk1)
—TRANSACTION 0 290327208, ACTIVE 1 sec, process no 3190, OS thread id 32782
58 lock struct (s), heap size 5504, undo log entries 159
MySQL thread id 23, query id 4668732 localhost heikki update
REPLACE INTO alexl VALUES(86, 46,
538, f aa95666 f , f bb', ! c95666 f , f d9486t l , f e200498f
',fg86814\ f
h538',date_format('2001-04-03 12:54:22','%Y-%m-%d %H:%i»),
-—TRANSACTION 0 290323325, ACTIVE 3 sec, process no 3185, OS thread id
30733 inserting
4 lock struct (s), heap size 1024, undo log entries 165
MySQL thread id 21, query id 4668735 localhost heikki update
INSERT INTO alexl VALUES(NULL, 49, NULL,faa42837', " ,•c56319','dl719t','',
NULL,г п32Г, NULL, NULL, 7.31,7.31,7.31,200)

FILE I/O

I/O thread 0 state: waiting for i/o request (insert buffer thread)
I/O thread 1 state: waiting for i/o request (log thread)
I/O thread 2 state: waiting for i/o request (read thread)
I/O thread 3 state: waiting for i/o request (write thread)
Pending normal aio reads: 0, aio writes: 0,
ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
Pending flushes (fsync) log: 0; buffer pool: 0
151671 OS file reads, 94747 OS file writes, 8750 OS fsyncs
25.44 reads/s, 18494 avg bytes/read, 17.55 writes/s, 2.33 fsyncs/s

INSERT BUFFER AND ADAPTIVE HASH INDEX

Ibuf for space 0: size 1, free list len 19, seg size 21,
85004 inserts, 85004 merged recs, 26669 merges
Hash table size 207619, used cells 14461, node heap has 16 buffer (s)
1877.67 hash searches/s, 5121.10 non-hash searches/s

LOG

Log sequence number 18 1212842764


9.12. Советы по настройке производительности InnoDB 567

Log flushed up to 18 1212665295


Last checkpoint at 18 1135877290
0 pending log writes, 0 pending chkp writes
4341 log i/o's done, 1.22 log i/o's/second

BUFFER POOL AND MEMORY

Total memory allocated 84966343; in additional pool allocated 1402624


Buffer pool size 3200
Free buffers 110
Database pages 3074
Modified db pages 2674
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages read 171380, created 51968, written 194688
28.72 reads/s, 20.72 creates/s, 47.55 writes/s
Buffer pool hit rate 999 / 1000

ROW OPERATIONS

0 queries inside InnoDB, 0 queries in queue


Main thread process no. 3004, id 7176, state: purging
Number of rows inserted 3738558, updated 127415, deleted 33707, read 755779
1586.13 inserts/s, 50.89 updates/s, 28.44 deletes/s, 107.88 reads/s

END OF INNODB MONITOR OUTPUT

1 row in set (0.05 sec)


Далее вы найдете некоторые примечания по выводу.
• Если раздел TRANSACTIONS содержит информацию по ожидаемым блокировкам, то
в вашем приложении может возникнуть конфликт блокировок. Выходные данные
также могут помочь при отслеживании причин возникновения взаимных блоки-
ровок.
• Раздел SEMAPHORES содержит информацию о потоках, ожидающих семафор, а так-
же статистические данные по количеству повторных циклов или ожиданий, вы-
полненных потоками для семафоров или блокировок чтения/записи. Большое ко-
личество потоков, ожидающих семафоры, может возникнуть в результате частого
выполнения дисковых операций ввода-вывода, а также может быть обусловлено
конфликтными ситуациями внутри самого механизма InnoDB. Конфликты могут
иметь место при большом количестве параллельных запросов или в случае про-
блем с планированием потоков в операционной системе. В подобных ситуациях
рекомендуется присвоить опции innodb_thread_concurrency значение меньше 8.
• В разделе BUFFER POOL AND MEMORY содержится статистическая информация по
записываемым и считываемым страницам. На основании этих сведений можно
вычислить количество выполняемых операций ввода-вывода для файла данных,
осуществляемых на данный момент в вашем запросе.
• Раздел ROW OPERATION показывает, что делает главный поток.
568 Глава 9. Механизм хранения InnoDB

9.13. Реализация многовариантности


Поскольку InnoDB является многовариантной базой данных, информация по старым
версиям строк хранится в табличном пространстве. Эта информация содержится в
структуре данных, которая по аналогии со структурой данных в Oracle называется сег-
ментом отката (rollback segment).
К каждой строке, хранящейся в базе данных, InnoDB добавляет по два поля. В 6-
байтовом поле хранится идентификатор последней транзакции, которая производила
вставку или обновление строки. Удаление также рассматривается как обновление, при
котором соответствующим образом помечается специальный бит удаления строки. Каж-
дая строка содержит также 7-байтовое поле, которое называется указателем отката (roll
pointer). Указатель отката указывает на запись в журнале отмены выполненных дейст-
вий, занесенную в сегмент отката. Если строка была обновлена, запись в этом журнале
будет содержать информацию, необходимую для восстановления содержимого строки
до обновления.
Информация из сегмента отката в базе данных InnoDB используется для отмены опе-
раций, которая необходима для отката транзакции. Она также используется при созда-
нии предыдущих версий строки для согласованного чтения.
Журналы отмены выполненных действий в сегменте отката разделяются на журналы
отмены вставок и журналы отмены обновлений. Журналы отмены вставок необходимы
только для отката транзакций и могут быть удалены сразу после фиксации транзакции.
Журналы отмены обновлений используются для согласованного чтения; их можно уда-
лять только после того, как не останется ни одной транзакции, которой InnoDB присваи-
вает копию, создающую при согласованном чтении раннюю версию строки на основе
информации из журнала отмены обновлений.
Не следует забывать о регулярной фиксации своих транзакций, включая те транзак-
ции, в которых применяется согласованное чтение. В противном случае InnoDB не смо-
жет удалить данные из журналов отмены обновлений, что приведет к увеличению раз-
меров сегмента отката, который может занять все ваше табличное пространство.
Физический размер записи журнала отмены в сегменте отката обычно меньше соот-
ветствующей вставленной или обновленной строки. Эту информацию можно использо-
вать для вычисления размера пространства, необходимого для сегмента отката.
В многовариантной схеме InnoDB строка физически не удаляется из базы данных по-
сле того, как она удаляется посредством SQL-оператора. Только после того, как InnoDB
сможет удалить запись в журнале отмены обновлений, занесенную для удаления, соот-
ветствующая строка и ее индексная запись из базы данных могут быть удалены физиче-
ски. Эта операция удаления называется чисткой (purge). Она производится достаточно
быстро - на нее уходит столько же времени, сколько и на выполнение оператора SQL-
удаления.

9.14. Структуры таблиц и индексов


MySQL хранит информацию своего словаря данных для таблиц в файлах . f rm, рас-
положенных в каталогах базы данных. Однако для каждой таблицы InnoDB имеются
также свои записи во внутренних словарях данных InnoDB в табличном пространстве.
Когда MySQL удаляет таблицу или базу данных, необходимо удалить как файлы . f rm,
так и соответствующие записи в словаре данных InnoDB. Именно поэтому нельзя пере-
9.14. Структуры таблиц и индексов 569

мещать таблицы innoDB между базами данных путем простого перемещения файлов
. f rm. По той же причине команда DROP DATABASE не работала для таблиц InnoDB в верси-
ях, предшествующих MySQL 3.23.43.
Для всех таблиц InnoDB имеется специальный индекс, в котором хранятся данные
строк - он называется кластеризованным индексом (clustered index). Если в таблице оп-
ределить первичный ключ (PRIMARY KEY), то индекс первичного ключа будет кластери-
зованным индексом.
Если первичный ключ для таблицы не был определен, MySQL будет использовать
первый индекс UNIQUE, который имеют только столбцы NOT NULL, в качестве первичного
ключа, и InnoDB рассматривает его как кластеризованный индекс. Если такого индекса в
таблице нет, то InnoDB самостоятельно создаст кластеризованный индекс, в котором
строки будут упорядочены по идентификаторам, присвоенным механизмом InnoDB стро-
кам этой таблицы. Идентификатор строки представляет собой 6-байтовое поле, значение
которого постоянно увеличивается при вставке новых строк. Таким образом, сортировка
по идентификатору строки фактически представляет собой сортировку по последова-
тельности вставки.
Доступ к строке через кластеризованный индекс осуществляется достаточно быстро,
поскольку данные строки находятся в той же странице, в которой производится поиск по
индексу. При больших размерах таблицы архитектура кластеризованных индексов за-
частую позволяет сократить количество дисковых операций ввода-вывода, если сравни-
вать ее с традиционными решениями.
Записи в некластеризованных индексах (которые называются вторичными индекса-
ми) в InnoDB содержат значение первичного ключа для строки. InnoDB использует это
значение первичного ключа для поиска строки в кластеризованном индексе. Следует
иметь в виду, что если первичный ключ будет достаточно велик, вторичные индексы
займут больше места.
InnoDB сравнивает потоки CHAR и VARCHAR разной длины таким образом, что остав-
шаяся длина в более короткой строке будет рассматриваться как строка, содержащая
пробелы.

9.14.1. Физическая структура индекса


Все индексы в InnoDB являются В-деревьями, в которых запись индекса сохраняется
в листовых страницах дерева. По умолчанию страница имеет размер 16 Кбайт. При
вставке новых записей InnoDB пытается оставить свободной 1/16 страницы для будущих
вставок и обновлений записей индекса.
Если записи индекса вставлены в последовательном порядке (восходящем или нис-
ходящем), то страница будет заполнена на 15/16. Если записи вставлены в случайном
порядке, страницы будут заполнены от 1/2 до 15/16. Если коэффициент заполнения
страницы будет меньше 1/2, InnoDB попытается сократить дерево индекса, чтобы осво-
бодить страницу.

9.14.2. Буферизация вставок


Нередко в программах для работы с базами данных первичный ключ является уни-
кальным идентификатором, и новые строки вставляются в порядке возрастания первич-
ного ключа. Таким образом, для вставки в кластеризованный индекс нет необходимости
проводить случайные считывания с диска.
570 Глава 9. Механизм хранения InnoDB

С другой стороны, вторичные индексы обычно не являются уникальными, поэтому


вставки во вторичные индексы производятся в относительно случайном порядке. Это
приводит к выполнению большого количества случайных дисковых операций ввода-
вывода, если не используется специальный механизм, применяемый в InnoDB.
Если требуется вставить запись индекса во вторичный индекс, который не является
уникальным, InnoDB проверяет, находится ли страница вторичного индекса в буферном
пуле. Если она там есть, InnoDB произведет вставку непосредственно в страницу индек-
са. Однако если страница индекса не будет найдена в буферном пуле, InnoDB вставит
запись в специальную структуру буфера вставок. Буфер вставок имеет настолько не-
большой размер, что может полностью поместиться в буферном пуле, и вставки в него
могут производиться очень быстро.
Буфер вставок периодически объединяется с деревьями вторичных индексов в базе
данных. Часто за счет объединения нескольких вставок на одной странице индексного
дерева можно сократить количество дисковых операций ввода-вывода. Использование
буфера вставки может ускорить процессы вставки в таблицу в 15 раз.

9.14.3. Адаптивный хешированный индекс


Если база данных практически вся умещается в основной памяти, то самым быстрым
способом выполнения запросов по этой базе данных является использование хеширо-
ванных индексов. В InnoDB существует автоматический механизм, который отслеживает
поиски по индексу, которые осуществляются по индексам, определенным для таблицы.
Если InnoDB посчитает, что запросы выиграют от создания хешированного индекса, та-
кой индекс будет создан автоматически.
Следует, однако, иметь в виду, что хешированный индекс всегда создается на основе
существующего индекса В-дерева таблицы. InnoDB может создать хешированный индекс
на префиксах любой длины ключа, определенного для В-дерева, в зависимости от того,
по какой схеме поиска InnoDB просматривается индекс В-дерева. Хешированный индекс
может быть частичным: не обязательно кэшировать в буферном пуле весь индекс В-
дерева. InnoDB будет создавать хешированные индексы по запросу для тех страниц ин-
декса, к которым часто производится доступ.
Хотя механизм адаптивного хешированного индекса InnoDB приспосабливается к
большому объему основной памяти, он больше подходит для архитектуры баз данных в
основной памяти.

9.14.4. Физическая структура записи


Записи в таблицах InnoDB имеют следующие характеристики:
• У всех записей индекса в InnoDB имеется заголовок, состоящий из 6 байт. Этот
заголовок используется для связывания вместе последовательных записей, а
также при блокировке на уровне строк.
• Записи в кластеризованном индексе содержат поля для всех столбцов, определен-
ных пользователем. Кроме этого, имеется поле в 6 байтов для идентификатора
транзакции и поле в 7 байт для указателя строки.
• Если пользователь не определил для таблицы первичный ключ, то в каждой запи-
си кластеризованного индекса также содержится 6-байтовое поле идентификатора
строки.
9.15. Управление файловым пространством и дисковый ввод-вывод 571

• Каждая запись вторичного индекса содержит все поля, определенные для ключа
кластеризованного индекса.
• Запись содержит указатель на каждое поле записи. Если общая длина полей в за-
писи будет меньше 128 байт, то указатель будет иметь размер в 1 байт, в против-
ном случае - 2 байта.
• InnoDB сохраняет столбцы фиксированной длины, такие как CHAR (10), в формате
фиксированной длины. InnoDB усекает завершающие пробелы в столбцах VARCHAR.
Учтите, что InnoDB может преобразовывать столбцы CHAR в VARCHAR.
• SQL-значение NULL занимает 0 байт при сохранении в столбце переменной длины.
В столбце фиксированной длины резервируется фиксированная длина. Необхо-
димость резервирования фиксированного пространства для значения NULL объяс-
няется тем, что замена значения NULL на другое отличное от него значение осуще-
ствляется на месте и не приводит к фрагментации индексной страницы.

9.15. Управление файловым пространством


и дисковый ввод-вывод
9.15.1. Дисковый ввод-вывод
В операциях дискового ввода-вывода для таблиц InnoDB используется асинхронный
ввод-вывод. InnoDB создает определенное количество потоков ввода-вывода, что позво-
ляет обеспечить выполнение таких операций ввода-вывода, как опережающее чтение.
В InnoDB используются два эвристических подхода к реализации опережающего чтения:
• При последовательном опережающем чтении InnoDB, определив, что схема досту-
па к сегменту в табличном пространстве является последовательной, будет зара-
нее направлять механизму ввода-вывода пакет считываний страниц базы данных.
• При случайном опережающем чтении InnoDB, определив, что некоторые части
табличного пространства полностью считываются в буферный пул, направляет
оставшиеся считывания механизму ввода-вывода.
Начиная с версии MySQL 3.23.41, в InnoDB используется новый способ сброса фай-
лов на диск, который получил название двойной записи (doublewrite). Он обеспечивает
высокую степень защиты при восстановлении после сбоя или отключении питания и
позволяет увеличить производительность в большинстве версий Unix за счет уменьше-
ния количества операций fsync ().
Двойная запись означает, что InnoDB перед записью страниц в файл данных сначала
записывает их в смежный участок табличного пространства, называемый буфером двой-
ной записи (doublewrite buffer). Запись страниц в предназначенные для них места в фай-
ле данных выполняется только после завершения записи и сброса буфера двойной запи-
си на диск. Если во время записи страницы произошел сбой, то во время восстановления
InnoDB найдет в буфере двойной записи подходящую копию страницы.
572 Глава 9. Механизм хранения InnoDB

9.15.2. Использование низкоуровневых устройств


для табличного пространства
Начиная с версии MySQL 3.23.41, в качестве файлов данных табличного пространст-
ва можно также использовать низкоуровневые диски. Используя низкоуровневый диск, в
Windows и в некоторых системах семейства Unix вы можете организовать ввод-вывод
без участия буфера, не перегружая файловую систему. Это позволяет улучшить показа-
тели производительности.
При создании нового файла данных непосредственно за размером файла данных в
опции innodb_data_f ile_path необходимо указать ключевое слово newraw. Раздел диска
должен быть больше указанного размера или равен ему. Обратите внимание: 1 Мбайт в
InnoDB - это 1024*1024 байт, тогда как в характеристиках диска 1 Мбайт обычно соот-
ветствует 1 000 000 байт.
[mysqld]
innodb_data_home_dir=
innodb_data_filejpath=/dev/hddl:3Gnewraw;/dev/hdd2:2Gnewraw
При новом запуске сервера InnoDB обнаруживает ключевое слово newraw и инициали-
зирует новый раздел. Однако пока не создавайте и не изменяйте таблицы InnoDB, по-
скольку после перезапуска сервера InnoDB повторно инициализирует раздел и внесенные
изменения будут утеряны. (Начиная с версий 3.23.44, в качестве меры предосторожно-
сти InnoDB запрещает изменять данные, если раздел указан как newraw.)
После того как InnoDB инициализирует новый раздел, необходимо остановить сервер
и заменить ключевое слово newraw на raw:
[mysqld]
i n n о db__da t a_h ome_d i r=
innodb_data_file_path=/dev/hddl:5Graw;/dev/hdd2:2Graw
Затем перезапустите сервер, теперь InnoDB разрешает производить изменения.
В Windows, начиная с версии MySQL 4.1.1, можно размещать раздел диска в виде
файла данных, как показано далее:
[mysqld]
innodb_data_home_dir=
innodb_data_file_path=//./D::10Gnewraw
Последовательность //./ соответствует синтаксису \\.\ в Windows, которые приме-
няется для доступа к физическим дискам.
С низкоуровневыми разделами диска должны быть связаны права доступа, имеющие
дело с учетными записями, которые используются при работе сервера MySQL.

9.15.3. Управление файловым пространством


Табличное пространство InnoDB составляют файлы данных, определенные в файле
конфигурации. Файлы попросту присоединяются друг к другу, что и приводит к форми-
рованию табличного пространства. Разделение данных на полосы в них не производится.
На данный момент невозможно непосредственно указать, где именно в табличном про-
странстве должны размещаться таблицы. Однако во вновь созданном табличном про-
странстве InnoDB распределяет пространство, начиная с первого файла данных.
9.15. Управление файловым пространством и дисковый ввод-вывод 573

Табличное пространство состоит из страниц базы данных, размер которых по умол-


чанию составляет 16 Кбайт. Эти страницы группируются в блоки, или экстенты (extent),
состоящие из 64 последовательно расположенных страниц. "Файлы" внутри табличного
пространства InnoDB называются "сегментами". Термин "сегмент отката" несколько не
соответствует действительности, поскольку на самом деле в нем содержится множество
сегментов табличного пространства.
Для каждого индекса в InnoDB выделяется два сегмента: один - для конечных узлов
В-дерева, а другой - для остальных узлов. Идея состоит в том, чтобы достичь более ор-
ганизованного расположения конечных узлов, в которых содержатся данные.
Когда сегмент внутри табличного пространства возрастает, то специально для него
InnoDB выделяет первые 32 страницы. После этого InnoDB начинает выделять для этого
сегмента целые области расширения. Чтобы обеспечить хорошую организацию данных,
InnoDB может добавить к большому сегменту до 4 областей расширения за один раз.
Некоторые страницы табличного пространства содержат битовые образы других
страниц, поэтому несколько экстентов в табличном пространстве InnoDB могут быть вы-
делены не для целых сегментов, а только для отдельных страниц.
После выдачи команды SHOW TABLE STATUS для получения информации о доступном
свободном пространстве в табличном пространстве InnoDB выводит отчет о свободных
экстентах. InnoDB всегда резервирует некоторые экстенты для выполнения очистки и
других внутренних операций. Зарезервированные экстенты в объем свободного про-
странства не включаются.
Если из таблицы удаляются данные, InnoDB объединяет соответствующие индексы В-
дерева. В зависимости от схемы удалений, когда освобождаются отдельные страницы
или экстенты табличного пространства, высвобожденная область становится доступной
другим пользователям. Удаление таблицы или удаление всех ее строк гарантированно
освободит пространство для других пользователей, но при этом не следует забывать, что
физически строки удаляются только после проведения очистки, после чего они стано-
вятся ненужными при откате транзакций или согласованном чтении.

9.15.4. Дефрагментация таблицы


Если в индексы таблицы выполнялись случайные вставки или удаления, индексы мо-
гут оказаться фрагментированными. Под фрагментацией понимается то, что физическое
расположение индексных страниц на диске существенно отличается от алфавитного по-
рядка страниц, или что в 64-страничных блоках, отведенных для индекса, присутствует
множество пустых страниц.
Скорость сканирования индекса можно увеличить с помощью команды ALTER TABLE:
ALTER TABLE шя_таблицы TYPE=InnoDB
При этом MySQL перестраивает таблицу. Существует еще один способ выполнить
дефрагментацию - воспользоваться командой mysqldump для копирования дампа табли-
цы в текстовый файл, записи диска на диск и повторной загрузки таблицы из дампа.
Если вставки в индекс всегда производятся последовательно, а удаления - только с
конца, то алгоритм управления файловым пространством InnoDB гарантирует отсутствие
фрагментации индекса.
574 Глава 9. Механизм хранения InnoDB

9.16. Обработка ошибок


Обработка ошибок в innoDB не всегда соответствует спецификациям стандарта SQL.
В соответствии со стандартом, любая ошибка, которая возникла во время выполнения
SQL-оператора, должна приводить к откату оператора. Иногда InnoDB реализует откат
только части оператора или целой транзакции. Ниже описаны особенности обработки
ошибок в InnoDB:
• Если свободное место в табличном пространстве закончилось, выдается сообще-
ние MySQL об ошибке Table is full (Таблица переполнена), и InnoDB выполня-
ет откат SQL-оператора.
• Взаимная блокировка транзакции или истечение времени ожидания при блоки-
ровке приводят к откату целой транзакции.
• Ошибка дублирования ключей приводит к откату вставки только данной опреде-
ленной строки, даже в операторе INSERT INTO.. .SELECT. Этот алгоритм, возмож-
но, будет изменен, чтобы можно было выполнять откат всего SQL-оператора, ес-
ли для него не указана опция IGNORE.
• Ошибка "row too long" ("слишком длинная строка") вызывает откат SQL-
оператора.
• Большинство остальных ошибок обнаруживается на уровне кода MySQL (выше
уровня механизма хранения InnoDB), и в случае их возникновения выполняется
откат соответствующего SQL-оператора.

9.16.1. Коды ошибок InnoDB


Ниже представлен перечень наиболее распространенных ошибок InnoDB, с которыми
вы можете столкнуться, а также сведения о том, почему они возникают и советы по ре-
шению проблем.
• 1005 (ER_CANT_CREATE_TABLE). Невозможно создать таблицу. Если уведомление об
ошибке ссылается на ошибку с номером 150, это означает, что создать таблицу не уда-
лось, поскольку ограничения внешнего ключа не были правильно сформулированы.
• 1016 (ER_CANT_OPEN_FILE). Невозможно найти таблицу InnoDB из файлов данных
InnoDB в файле . f rm для существующей таблицы. См. раздел 9.18.1.
• 1114 (ER_RECORD_FILE_FULL). Механизм InnoDB исчерпал свободное место в таб-
личном пространстве. Чтобы добавить новый файл данных, потребуется заново
конфигурировать табличное пространство.
• 1205 (ER_LOCK_WAIT_TIMEOUT). Время ожидания блокировки истекло. Произошел
откат транзакции.
• 1213 (ER_LOCK_DEADLOCK). Взаимная блокировка транзакции. Необходимо по-
вторно запустить транзакцию.
• 1216 (ER_NO_REFERENCED_ROW). Попытка добавления строки при отсутствии роди-
тельской строки; сбой ограничения внешнего ключа. Необходимо добавить сна-
чала родительскую строку.
• 1217 (ER_ROW_IS_REFERENCED). Попытка удалить родительскую строку, имеющую
дочерние строки; сбой ограничения внешнего ключа. Необходимо удалить снача-
ла дочерний ряд.
9.16. Обработка ошибок 575

9.16.2. Коды ошибок операционной системы


Для вывода содержания ошибки операционной системы служит программа perror,
входящая в состав дистрибутива MySQL.
Ниже представлен список некоторых распространенных кодов ошибок сис-
темы Linux. Более подробно о них можно узнать в исходном коде Linux
(http://www.iglu.org.i1/lxr/source/include/asrai386/errno.h).
• 1 (EPERM). Запрет на выполнение операции.
• 2 (ENOENT). Такой файл или каталог отсутствует.
• 3 (ESRCH). Такой процесс отсутствует.
• 4 (EINTR). Прерванный системный вызов.
• 5 (ЕЮ). Ошибка ввода-вывода.
• 6 (ENXIO). Такое устройство или адрес отсутствует.
• 7 (E2BIG). Слишком большой список аргументов.
• 8 (ENOEXEC). Ошибка формата исполняемого файла.
• 9 (EBADF). Неверный номер файла.
• 10 (ECHILD). Отсутствуют дочерние процессы.
• 11 (EAGAIN). Попытайтесь повторить операцию.
• 12 (ENOMEM). Недостаточно памяти.
• 13 (EACCES). В доступе отказано.
• 14 (EFAULT). Неверный адрес.
• 15 (ENOTBLK). Требуется блокировка устройства.
• 16 (EBUSY). Занято устройство или ресурс.
• 17 (EEXIST). Файл существует.
• 18 (EXDEV). Ссылки между устройствами.
• 19 (ENODEV). Такое устройство отсутствует.
• 20 (ENOTDIR). Это не каталог.
• 21 (EISDIR). Это каталог.
• 22 (EINVAL). Неверный аргумент.
• 23 (ENFILE). Переполнение таблицы файлов.
• 24 (EMFILE). Слишком много открытых файлов.
• 25 (ENOTTY). Несоответствующий i o c t l для устройства.
• 26 (ETXTBSY). Текстовый файл занят.
• 27 (EFBIG). Слишком большой файл.
• 28 (ENOSPC). Свободное место на устройстве отсутствует.
• 29 (ESPIPE). Неразрешенный поиск.
• 3 0 (EROFS). Файловая система только для чтения.
• 31 (EMLINK). Слишком много ссылок.
576 Глава 9. Механизм хранения InnoDB

Далее следует перечень некоторых распространенных кодов ошибок системы


Windows. Более подробно о них можно узнать на сайте Microsoft по адресу:
http://msdn.microsoft.com/library/default.asp?url=/library/
en-us/debug/base/system_error_codes.asp
• 1 (ERROR_INVALID_FUNCTION). Недопустимая функция.
• 2 (ERROR_FILE_NOT_FOUND). Система не может найти указанный файл.
• 3 (ERROR_PATH_NOT_FOUND). Система не может найти указанный путь.
• 4 (ERROR_TOO_MANY_OPEN_FILES). Система не может открыть файл.
• 5 (ERROR_ACCESS_DENIED). В доступе отказано.
• б (ERROR_INVALID_HANDLE). Недопустимый дескриптор.
• 7 (ERROR_ARENA__TRASHED). Блоки управления памятью разрушены.
• 8 (ERROR_NOT_ENOUGH_MEMORY). Недостаточно памяти для выполнения команды.
• 9 (ERROR_INVALID_BLOCK). Недопустимый адрес блока управления памятью.
• 10 (ERRORJBAD_ENVIRONMENT). Недопустимая среда.
• 11 (ERROR_BAD_FORMAT). Попытка загрузить программу с недопустимым форматом.
• 12 (ERROR_INVALID_ACCESS). Неверный код доступа.
• 13 (ERROR_INVALID_DATA). Недопустимые данные.
• 14 (ERROR_OUTOFMEMORY). Недостаточно памяти для завершения этой операции.
• 15 (ERROR_INVALID_DRIVE). Система не может найти указанное устройство.
• 16 (ERROR_CURRENT_DIRECTORY). Этот каталог не может быть удален.
• 17 (ERROR_NOT_SAME_DEVICE). Система не может переместить файл на другое
дисковое устройство.
• 18 (ERROR_NO_MORE_FILES). Файлов больше нет.
• 19 (ERROR_WRITE_PROTECT). Носитель защищен от записи.
• 20 (ERROR_BAD_UNIT). Система не может найти указанное устройство.
• 21 (ERROR_NOT_READY). Устройство не готово.
• 22 (ERROR_BAD_COMMAND). Устройство не распознает команду.
• 23 (ERROR_CRC). Ошибка в данных (циклический код с избыточностью).
• 24 (ERROR_BAD_LENGTH). Программа выдала команду с недопустимой длиной.
• 25 (ERROR_SEEK). Дисковое устройство не может обнаружить указанную область
или дорожку.
• 26 (ERROR_NOT_DOS__DISK). Нет доступа к указанному диску или дискете.
• 27 (ERROR_SECTOR_NOT_FOUND). Дисковое устройство не может обнаружить за-
прошенный сектор.
• 28 (ERROR_OUT_OF_PAPER). В принтере закончилась бумага.
• 29 (ERROR_WRITE_FAULT). Система не может выполнить запись на указанное уст-
ройство.
• 30 (ERRORREADFAULT) .Система не может выполнить чтение с указанного устройства.
9.17. Ограничения таблиц InnoDB 577

• 31 (ERROR_GEN_FAILURE). Устройство, подключенное к системе, не работает.


• 32 (ERROR_SHARING_VIOLATION). Процесс не имеет доступа к файлу, поскольку
файл используется другим процессом.
• 33 (ERROR_LOCK_VIOLATION). Процесс не имеет доступа к файлу, поскольку дру-
гой процесс заблокировал часть файла.
• 34 (ERROR_WRONG_DISK). Вставьте другую дискету. Вставьте %2 (серийный номер
тома: %3) в дисковод % 1 .
• 36 (ERROR_SHARING_BUFFER_EXCEEDED). СЛИШКОМ МНОГО фаЙЛОВ ОТКрЫТО ДЛЯ СО-

вместного использования.
• 38 (ERROR_HANDLE_EOF). Достигнут конец файла.
• 39 (ERRORJiANDLE_DlSK_FULL). Отсутствует место на диске.
• 112 (ERROR_DISK_FULL). Отсутствует место на диске.
• 123 (ERROR_INVALID_NAME). Неверный синтаксис имени файла, каталога или мет-
ки тома.
• 1450 (ERROR_NO__SYSTEM_RESOURCES). Недостаточно системных ресурсов для за-
вершения затребованной службы.

9.17. Ограничения таблиц InnoDB


• Таблица не может содержать более 1000 столбцов.
• Максимальная длина ключа составляет 1024 байта.
• Максимальная длина строки, за исключением столбцов BLOB и TEXT, чуть меньше
половины страницы базы данных; то есть, максимальная длина строки составляет
приблизительно 8000 байт. Длина столбцов LONGBLOB и LONGTEXT должна быть ме-
нее 4 Гбайт, а общая длина строки, включая столбцы BLOB и TEXT, - менее 4 Гбайт.
InnoDB сохраняет первые 512 байт столбца BLOB и TEXT в строке, а остальные пе-
реносит на отдельные страницы.
• В некоторых операционных системах файлы данных должны иметь размер до
2 Гбайт.
• Комбинированный размер файлов журналов InnoDB должен быть менее 4 Гбайт.
• Минимальный размер табличного пространства составляет 10 Мбайт. Макси-
мальный размер табличного пространства составляет 4 триллиона страниц базы
данных (64 Тбайт), что является также максимальным размером таблицы.
• Таблицы InnoDB не поддерживают индексы FULLTEXT.
• В среде Windows механизм InnoDB всегда хранит имена баз данных и таблиц в
нижнем регистре. Чтобы перенести базы данных в двоичном формате из Unix в
Windows или наоборот, необходимо, чтобы имена всех баз данных и таблиц были
представлены буквами нижнего регистра.
| Предупреждение
Щ Не преобразовывайте системные таблицы MySQL в базе данных mysql из My ISAM в InnoDB!
Ж Эта операция не поддерживается. Если вы это сделаете, MySQL не будет запускаться до тех
| пор, пока вы не восстановите старые системные таблицы из резервной копии или не сгенерируе-
fj те их с помощью сценария mysql_install_db.
578 Глава 9. Механизм хранения InnoDB

• InnoDB не выполняет внутренний подсчет строк в таблице. (Это слишком сложно


по причине поддержки многовариантности.) Чтобы обработать оператор SELECT
COUNT(*) FROM T, механизм InnoDB должен сканировать индекс таблицы, на что
потребуется некоторое время, если не вся таблица находится в буферном пуле.
Для быстрого подсчета лучше пользоваться счетчиком таблицы, который вы
должны создать сами, и позволить вашему приложению обновляться в соответст-
вии с операциями вставки и удаления. Если ваша таблица изменяется редко, тогда
лучше всего использовать кэш запросов MySQL. Можно выдавать также и коман-
ду SHOW TABLE STATUS, если интересует только приблизительный подсчет строк.
См. раздел 9.12.
• Для столбца AUTOINCREMENT всегда следует указывать индекс для таблицы. Этот
индекс должен содержать только столбец AUTOINCREMENT. В таблицах My ISAM
столбец AUTOINCREMENT может быть частью индекса с множеством столбцов.
• InnoDB не использует параметр таблицы AUTO_INCREMENT для настройки значения
первоначальной последовательности в операторе CREATE TABLE или ALTER TABLE.
Чтобы настроить значение с помощью InnoDB, вставьте фиктивную строку с
меньшим значением и удалите эту фиктивную строку, либо вставьте первую
строку с явно указанным значением.
• Во время перезапуска сервера MySQL InnoDB может вновь использовать старое
значение для столбца AUTOINCREMENT (то есть, значение, которое было присвоено
отклоненной старой транзакции).
• Когда в столбце AUTOINCREMENT количество возможных значений превышает
норму, InnoDB присваивает BIGINT значение -9223372036854775808, a BIGINT
UNSIGNED - значение 1. Для значений BIGINT используется 64 бита, поэтому имей-
те в виду, что если вы выполняли вставку одного миллиона строк в секунду,
пройдет около миллиона лет, прежде чем BIGINT достигнет своей верхней грани-
цы. Во всех других столбцах целочисленного типа возникнет ошибка дублирова-
ния ключей. То же самое характерно и для механизма MylSAM - это обычное пове-
дение MySQL, а не какого-то механизма хранения.
• Оператор DELETE FROM имя_таблицыне генерирует таблицу, а удаляет все строки,
одну за другой.
• TRUNCATE имя_ та блицы соответствует DELETE FROM имя__таблицы в InnoDB и не об-
нуляет счетчик AUTO__INCREMENT.
• Команда SHOW TABLE STATUS не выдает точную статистику по таблицам InnoDB, за
исключением физического размера, зарезервированного таблицей. Счетчик строк
используется только для приближенной оценки для оптимизации SQL.
• Если вы попытаетесь создать уникальный индекс в префиксе столбца, будет
сгенерирована ошибка:
CREATE TABLE T (A CHAR(20), В INT, UNIQUE (A(5))) TYPE = InnoDB;
Если вы создаете неуникальный индекс в префиксе столбца, InnoDB создаст ин-
декс по всему столбцу.
В версиях MySQL 4.0.14 и 4.1.1 эти ограничения сняты.
• Команда INSERT DELAYED для таблиц InnoDB не поддерживается.
9.18. Поиск и устранение неполадок в InnoDB 579

• Операции MySQL LOCK TABLES ничего не известно о блокировках на уровне строк


в InnoDB, установленных уже выполненными SQL-операторами. Это означает, что
таблица может оказаться заблокированной даже при существующих транзакциях
других пользователей, у которых в данной таблице установлены блокировки на
уровне строк. Таким образом, выполнение ваших операций над таблицей может
быть отложено, если они столкнутся с блокировками, установленными другими
пользователями. Возможно также появление взаимных блокировок. Однако это не
означает, что целостность транзакций может быть нарушена, поскольку блоки-
ровки на уровне строк, устанавливаемые InnoDB, всегда отслеживают целост-
ность. Кроме того, если таблица будет заблокирована, то транзакции не смогут
установить в ней большее количество блокировок на уровне строки (в режиме
конфликтующих блокировок).
• До выхода версии MySQL 3.23.52 репликация всегда выполнялась в режиме авто-
матической фиксации. Поэтому процессам согласованного чтения на подчинен-
ном сервере также могли быть видимы частично обработанные транзакции, по-
этому чтение на подчиненном сервере не было действительно согласованным. Это
ограничение было снято в MySQL 3.23.52.
• Оператор LOAD TABLE FROM MASTER для настройки репликации на подчиненных
серверах пока что не работает. В качестве альтернативы на главном сервере мож-
но изменить формат таблицы на My ISAM, выполнить загрузку, а затем изменить
формат главной таблицы снова на InnoDB.
• По умолчанию размер страницы базы данных в InnoDB составляет 16 Кбайт.
После повторной компиляции можно установить другой размер в диапазоне от
8 Кбайт до 64 Кбайт. Потребуется обновить значения UNIV_PAGE_SIZE и
UNIV_PAGE_SIZE_SHIFT в файле исходного кода univ.i.

9.18. Поиск и устранение неполадок в InnoDB


• Существует общее правило: когда происходит сбой при выполнении какой-то
операции, или если вы подозреваете о существовании программной ошибки, не-
обходимо просмотреть журнал ошибок сервера MySQL, который обычно имеет
имя наподобие имя_хоста. err или mysql. err в Windows.
• При поиске неполадок лучше всего запустить сервер MySQL из командной стро-
ки, а не с помощью оболочки mysqld_safe или как службу Windows. Вы сможете
следить за информацией, выводимой mysqld в окне командной строки, и будете
осведомлены о происходящих событиях. В Windows сервер должен быть запущен
с опцией —console, в результате чего выходная информация будет направляться
в окно консоли.
• Чтобы получить сведения о возникшей проблеме, используйте мониторы InnoDB.
Если проблема связана со снижением показателей производительности, или если
ваш сервер зависает, попробуйте воспользоваться монитором innodbmonitor, ко-
торый выводит информацию о внутреннем состоянии InnoDB. Если эта проблема
связана с блокировками, используйте монитор innodb_lock_monitor. Если про-
блема связана с созданием таблиц или с другими операциями словаря данных, ис-
пользуйте монитор innodb_table_monitor, который выводит информацию о со-
держимом внутреннего словаря данных InnoDB.
580 Глава 9. Механизм хранения InnoDB

• Если вы подозреваете, что таблицы повреждена, запустите для нее команду CHECK
TABLE.

9.18.1. Поиск и устранение неполадок в операциях


словаря данных InnoDB
Особенность таблиц заключается в том, что сервер MySQL хранит информацию сло-
варя данных в файлах . f rm, которые расположены в каталогах баз данных, в то время
как InnoDB хранит информацию в своем собственном словаре данных в файлах таблич-
ного пространства. Если вы перемещаете файлы . frm или используете команду DROP
DATABASE в версиях MySQL, предшествующих 3.23.44, или если происходит сбой серве-
ра во время выполнения операций со словарем данных, файлы . frm могут рассинхрони-
зироваться со словарем данных InnoDB.
Признаком нарушения синхронизации словаря данных является сбой при работе опе-
ратора CREATE TABLE. Если это произошло, просмотрите журнал ошибок сервера. Если в
этом журнале вы найдете запись о том, что таблица уже существует внутри словаря дан-
ных InnoDB, значит, вы имеете дело с "висячей" таблицей в файлах табличного про-
странства InnoDB, для которой отсутствует соответствующий файл .frm. Сообщение об
ошибке выглядит следующим образом:
InnoDB: Error: table test/parent already exists in InnoDB internal
InnoDB: data dictionary. Have you deleted the .frm file
InnoDB: and not used DROP TABLE? Have you used DROP DATABASE
InnoDB: for InnoDB tables in MySQL version <= 3.23.43?
InnoDB: See the Restrictions section of the InnoDB manual.
InnoDB: You can drop the orphaned table inside InnoDB by
InnoDB: creating an InnoDB table with the same name in another
InnoDB: database and moving the .frm file to the current database.
InnoDB: Then MySQL thinks the table exists, and DROP TABLE will
InnoDB: succeed.
InnoDB: Ошибка: таблица test/parent уже существует во внутреннем
InnoDB: словаре данных InnoDB. Возможно, вы удалили файл .frm и
InnoDB: не использовали для этого DROP TABLE. Возможно, вы использовали
InnoDB: DROP DATABASE для таблиц InnoDB в версии MySQL до 3.23.43.
InnoDB: См. раздел "Restrictions" ("Ограничения") в руководстве по InnoDB.
InnoDB: Вы можете удалить "висячую" таблицу внутри InnoDB,
InnoDB: создав таблицу InnoDB с тем же именем в другой
InnoDB: базе данных и переместив файл .frm в текущую базу данных.
InnoDB: В результате MySQL воспримет эту таблицу как существующую, и
InnoDB: DROP TABLE выполнится.
Такую таблицу можно удалить, выполнив указания, представленные в сообщении об
ошибке.
Другим признаком нарушения синхронизации словаря данных является то, что
M y S Q L выводит ошибку о невозможности открыть файл . InnoDB:
f
ERROR 1016: Can't open file: child2.InnoDB'. (errno: 1)
В журнале ошибок вы увидите следующее сообщение:
InnoDB: Cannot find table test/child2 from the internal data dictionary
InnoDB: of InnoDB though the .frm file for the table exists. Maybe you
9.18. Поиск и устранение неполадок в InnoDB 581

InnoDB: have deleted and recreated InnoDB data f i l e s but have forgotten
InnoDB: to delete the corresponding .frm files of InnoDB tables?
InnoDB: Невозможно найти таблицу test/child2 во внутреннем словаре данных
InnoDB: InnoDB, хотя файл .frm для этой таблицы существует.
InnoDB: Возможно, вы удалили и повторно создали файлы данных InnoDB,
InnoDB: но забыли удалить соответствующие файлы .frm для таблиц InnoDB.
Это сообщение свидетельствует о существовании "висячего" файла . frm, не имею-
щего соответствующей таблицы в InnoDB. Этот файл можно удалить вручную.
Если происходит сбой MySQL во время выполнения операции ALTER TABLE, все мо-
жет закончиться появлением "висячей" временной таблицы в табличном пространстве
InnoDB. Запустив монитор innodb_table_monitor, можно увидеть таблицу с именем
# s q l . . . , однако поскольку MySQL не предоставляет доступ к таблице с таким именем,
вы не сможете удалить ее или выполнить дамп. Выход заключается в использовании
специального механизма, который доступен в версии MySQL 3.23.48.
Если вы обнаружили "висячую" таблицу #sql_id в табличном пространстве, ей мож-
но присвоить новое имя rsql_id_recover__innodb_tmp_table с помощью следующего
оператора:
CREATE TABLE ч rsql_id_recover_innodb__tmp_table 4 (...) TYPE=InnoDB;
Обратные кавычки, в которые заключено имя, необходимы потому, что в имени про-
межуточной таблицы присутствует символ '-'.
Описание таблицы должно быть похожим на описание временной таблицы. Если вам
не известно описание временной таблицы, можно использовать произвольное описание
в предыдущем операторе CREATE TABLE и заменить файл rsql_id.frm на файл
#sql_id.frm временной таблицы. Обратите внимание на то, что для копирования или
переименования файла в среде оболочки необходимо заключить имя файла в двойные
кавычки, если в имени файла присутствует символ '#'. Затем вы сможете выполнить
дамп и удалить переименованную таблицу.
10
Введение в MaxDB

м axDB - это база данных уровня предприятия. MaxDB представляет собой новое
имя системы управления базами данных, ранее известной как SAP DB.

10.1. История MaxDB


История SAP DB восходит к началу 80-х годов прошлого века, когда она была разра-
ботана как коммерческий продукт (Adabas). С тех пор она несколько раз меняла назва-
ния. Когда SAP AG, компания, находящаяся в Валдорфе (Walldorf), Германия, взялась за
разработку этой системы управления базами данных, она получила название SAP DB.
Компания SAP разрабатывала эту систему для обслуживания хранилищ данных для
всех тяжело нагруженных приложений SAP, а именно - для R/3. Предполагалось, что
SAP DB станет альтернативой для систем от независимых поставщиков, таких как
Oracle, Microsoft SQL Server и DB2 от IBM. В октябре 2000 года SAP AG выпустила SAP
DB под лицензией GNU GPL, таким образом, сделав ее программным продуктом с от-
крытым исходным кодом. В октябре 2003 года более чем 2000 заказчиков SAP AG
применяли SAP DB в качестве основной системы управления базами данных, и более
чем 2000 других пользователей применяли ее как дополнительную систему, работаю-
щую наряду с основной системой управления базами данных, как часть решения
APO/LiveCache.
В мае 2003 года между компаниями MySQL AB и SAP AG были установлены парт-
нерские отношения. В результате этого компания MySQL AB получила права на даль-
нейшую разработку системы SAP DB, ее переименование и выдачу коммерческих ли-
цензий на переименованный продукт тем заказчикам, которые не хотели быть связан-
ными ограничениями, накладываемыми лицензией GNU GPL. В августе 2003 года SAP
DB получила новое название - MaxDB.

10.2. Лицензирование и поддержка


MaxDB может использоваться на основе тех же лицензий, что и все продукты, рас-
пространяемые компанией MySQL AB. To есть MaxDB доступна как на условиях лицен-
зии GNU General Public License, так и по коммерческой лицензии. Более подробная ин-
формация о лицензировании и поддержке представлена в разделе 1.4.
MySQL предложит поддержку MaxDB тем пользователям, которые не относятся к
числу заказчиков SAP.
10.5. Отличия возможностей MaxDB и MySQL 583

Первая переименованная версия под названием MaxDB 7.5.00 вышла в ноябре 2003
года.

10.3. Ссылки, касающиеся MaxDB


Главная страница с информацией о MaxDB - это http: //www.mysql. com/products/maxdb.
Информация, ранее доступная по адресу http://www.sapdb.org, также была переме-
щена сюда.

10.4 Базовые концепции MaxDB


Система MaxDB функционирует как клиент-серверный продукт. Она была разрабо-
тана для того, чтобы отвечать требованиям установок, обрабатывающих высокий уро-
вень нагрузки онлайновых транзакций. Поддерживается как онлайновое резервирование,
так и расширение системы. Microsoft Clustered Server поддерживается непосредственно
для множества серверных реализаций, другие устойчивые решения могут быть запро-
граммированы вручную. Инструменты управления базой данных предоставляется как в
виде Windows-реализаций, так и ориентированных на браузеры.

10.5. Отличия возможностей MaxDB и MySQL


Следующий неполный список подводит краткий итог основных различий между
MaxDB и MySQL:
• MaxDB функционирует как клиент-серверная система. MySQL может функцио-
нировать и как клиент-серверная, и как встроенная система.
• MaxDB работает не на всех платформах, поддерживаемых MySQL. Например,
MaxDB не работает под управлением IBM OS/2.
• MaxDB использует собственный сетевой протокол для клиент-серверных комму-
никаций. MySQL использует TCP/IP (с SSL-шифрованием и без него), сокеты (в
Unix-подобных системах) или именованные каналы (в системах семейства
Windows NT).
• MaxDB поддерживает хранимые процедуры. В MySQL хранимые процедуры реа-
лизованы в версии 5.0. MaxDB также поддерживает программирование триггеров
через расширение SQL, реализация которого запланирована в MySQL 5.1. MaxDB
содержит отладчик для языков хранимых процедур, поддерживает каскадирова-
ние вложенных триггеров, а также множество триггеров уровня операции и уров-
ня строки.
• MaxDB распространяется с текстовыми, графическими и Web-ориентированными
интерфейсами пользователя. MySQL - только с текстовыми интерфейсами, а ин-
струменты с графическим пользовательским интерфейсом (MySQL Control Center,
MySQL Administrator) поставляются отдельно от основного дистрибутива. Web-
ориентированные инструменты для MySQL предлагаются независимыми разра-
ботчиками.
• MaxDB поддерживает определенное количество программных интерфейсов, ко-
торые поддерживаются также и MySQL. Однако MaxDB не поддерживает RDO,
ADO или .NET, которые поддерживаются в MySQL. MaxDB поддерживает встро-
енный SQL только для C/C++.
584 Глава 10. Введение в MaxDB

• MaxDB включает административные средства, которых нет у MySQL: планирова-


ние заданий по времени, события, сигналы тревоги (alerts) и отправку сообщений
администратору базы данных по достижению каких-либо пороговых значений.

10.6. Средства взаимодействия между


MaxDB и MySQL
Следующие средства будут включены в новые версии MaxDB, которые планируются
к выходу вскоре после 7.5.00. Эти средства должны обеспечить взаимодействие MaxDB
с MySQL.
• Будет обеспечена возможность прокси-подключений MySQL к MaxDB с исполь-
зованием протокола MySQL. Это позволит использовать клиентские программы
MySQL для MaxDB, такие как утилита командной строки mysql, утилита выгруз-
ки дампа mysqldump и программа импорта mysqlimport. Используя mysqldump,
можно будет легко выгружать дамп из одной системы управления базами данных
и импортировать (или даже передавать по программному каналу) в другую.
• Репликация между MySQL и MaxDB будет поддерживаться в обоих направлени-
ях. То есть и сервер MySQL, и сервер MaxDB сможет служить главным сервером
репликации. Долгосрочные планы включают объединение и расширение синтак-
сиса репликации таким образом, чтобы обе системы понимали один синтаксис.
См. раздел 5.1.

10.7. Зарезервированные слова MaxDB


Как и MySQL, MaxDB имеет определенное число зарезервированных слов, которые
имеют специальное значение.
Обычно они не могут быть использованы в качестве имен идентификаторов, таких
как имена баз данных или таблиц. В табл. 10.1 перечислены зарезервированные слова
MaxDB, описан контекст их использования и приведены соответствия из MySQL. Если
соответствующие позиции в MySQL существуют, их значение в MySQL может быть
идентичным или отличающимся в некоторых аспектах. Главная цель - перечислить, в
каких моментах MaxDB отличается от MySQL, следовательно, этот список не полон.
Таблица ЮЛ. Зарезервированные слова MaxDB и их соответствия в MySQL
Зарезервирова- Контекст применения
но в MaxDB в MaxDB Соответствие MySQL
@ Префикс идентификатора, Не предусмотрено
как "@table"
ADDATE () Функция SQL ADDATE (), новая в MySQL 4.1.1
ADDTIMEO Функция SQL ADDTIME (), новая в MySQL 4.1.1
ALPHA Функция SQL Нет соответствия
ARRAY Тип данных Не реализовано
A S C I I () Функция SQL ASCII (), но реализовано в другом значении
AUTOCOMMIT Транзакции, по умолчанию Транзакции, по умолчанию OFF (выключено)
ON (включено)
10.7. Зарезервированные слова MaxDB 585

Продолжение табл. ЮЛ
Зарезервирова- Контекст применения
но в MaxDB в MaxDB Соответствие MySQL
BOOLEAN Тип столбца, принимает BOOLEAN был добавлен в MySQL 4.1.0, синоним
только значения для BOOL, отображаемого на TINYINT (1). При-
TRUE, FALSE или NULL нимает значения в том же диапазоне, что
TINYINT, также, как и NULL. TRUE и FALSE мо-
гут использоваться как синонимы 1 и О
CHECK Проверка таблицы CHECK TABLE - похожее, но не идентичное
применение
COLUMN Типы столбцов COLUMN, излишнее слово
CHAR() Функция SQL CHAR () - идентичный синтаксис, похожее, но
не идентичное применение.
COMMIT Явная фиксация транзакций Явно фиксирует транзакцию, выполняется по-
выполняемая после операто сле оператора определения данных, а также
ра определения данных после многих других операторов
COSHO Функция SQL Нет соответствия
сото Функция SQL СОТ () - идентичный синтаксис и реализация
CREATE SQL, язык определения CREATE
данных
DATABASE Функция SQL DATABASE ( ) ; DATABASE применяется в другом
контексте, например, CREATE DATABASE
DATE() Функция SQL CURRENT_DATE
DATEDIFFO Функция SQL DATEDIFF ( ) , новая в MySQL 4.1.1
DAY() Функция SQL Нет соответствия
DAYOFWEEK() Функция SQL DAYOFWEEK ( ) , по умолчанию 1, означает поне-
дельник в MaxDB и воскресенье в MySQL
DISTINCT Функции SQL DISTINCT, но применяется в другом контексте:
AVG, MAX, MIN, SUM SELECT DISTINCT
DROP DROP INDEX, DROP INDEX, похожее, но не идентичное
например применение
EBCDIC () Функция SQL Нет соответствия
EXPAND () Функция SQL Нет соответствия
EXPLAIN Оптимизация EXPLAIN, похожее, но не идентичное применение
FIXED () Функция SQL Нет соответствия
FLOAT () Функция SQL Нет соответствия
HEX() Функция SQL HEX ( ) , похожее, но не идентичное применение
INDEX () Функция SQL INSTR () или LOCATE ( ) , похожие, но не
идентичные синтаксис и значение
586 Глава 10. Введение в MaxDB

Продолжение табл. 10.1


Зарезервирова- Контекст применения
но в MaxDB в MaxDB Соответствие MySQL
INDEX USE INDEX, IGNORE INDEX USE INDEX, IGNORE INDEX и подобные
и тому подобные случаи, варианты применяются в конструкции
используется непосредствен- FROM оператора SELECT; например, в
но после SELECT; например, SELECT...FROM...USE INDEX
в SELECT...USE INDEX
INITCAPO Функция SQL Нет соответствия
LENGTH() Функция SQL LENGTH (), идентичный синтаксис, но немного
другая реализация
LFILLO Функция SQL Нет соответствия
LIKE Сравнения LIKE, но расширенный LIKE из MaxDB
представляет возможности MySQL REGEX
LIKE шаблоны В качестве шаблонов для MySQL поддерживает в качестве шаблонов
LIKE MaxDB поддерживает только "%" и " "
"%"," ", " C o n t r o l -
u n d e r l i n e " , "Control-up
arrow", " * " и " ? "
LPAD() Функция SQL LPAD (), немного другая реализация
LTRIMO Функция SQL LTRIM (), немного другая реализация
MAKEDATEO Функция SQL MAKEDATE (), новая в MySQL 4.1.1
МАКЕТ I M E ( ) Функция SQL МАКЕТIME (), новая в MySQL 4.1.1
MAPCHARO Функция SQL Нет соответствия
MICROSECOND() Функция SQL MICROSECOND (), новая в MySQL 4.1.1
NOROUND() Функция SQL Нет соответствия
NULL Типы колонок, сравнения NULL; MaxDB поддерживает специальные зна-
чения NULL, которые возвращаются арифмети-
ческими операциями, приводящими к перепол-
нению, или при делении на ноль. MySQL не
поддерживает таких специальных значений.
PI Функция SQL PI (), идентичный синтаксис и реализация,
но в MySQL скобки обязательны
REF Тип данных Нет соответствия
RFILLO Функция SQL Нет соответствия
ROWNO Предикат в конструкции Аналог конструкции LIMIT
WHERE

RPAD() Функция SQL RPAD (), немного другая реализация


RTRIM() Функция SQL RTRIM (), немного другая реализация
SEQUENCE CREATE SEQUENCE,DROP AUTO_INCREMENT, похожая концепция,
SEQUENCE но другая реализация
10.7. Зарезервированные слова MaxDB 587

Окончание табл. 10.1

Зарезервирова- Контекст применения


но в MaxDB в MaxDB Соответствие MySQL

SINHO Функция SQL Нет соответствия


SOUNDS () Функция SQL SOUNDEX ( ) , немного другой синтаксис
STATISTICS UPDATE STATISTICS ANALYZE TABLE, похожая концепция,
но другая реализация
SUBSTRO Функция SQL SUBSTRING ( ) , слегка другая реализация
SUBTIMEO Функция SQL SUBTIME ( ) , новая в MySQL 4.1.1
SYNONYM Язык определения данных: Нет соответствия
CREATE [PUBLIC] SYNONYM,
RENAME SYNONYM,
DROP SYNONYM
TANHO Функция SQL Нет соответствия
TIMEO Функция SQL CURRENT_TIME
TIMEDIFFO Функция SQL TIMEDIFF ( ) , новая в MySQL 4.1.1
TIMESTAMPO Функция SQL TIMESTAMP ( ) , новая в MySQL 4.1.1

TIMESTAMPO Функция SQL Нет соответствия


как аргумент
для
DAYOFMONTHO
и DAYOFYEAR()
TIMEZONEO Функция SQL Нет соответствия
TRANSACTION() Возвращает идентификатор Нет соответствия
текущей транзакции
TRANSLATE() Функция SQL REPLACE ( ) , идентичный синтаксис и реализация

TRIMO Функция SQL TRIM ( ) , немного другая реализация

TRUNCO Функция SQL TRUNCATEO, немного другой синтаксис


и реализация
USE Закрывает подключение к Переключается на другую базу
текущей базе данных, пере-
ключается на другую базу
USER Функция SQL USER ( ) , идентичный синтаксис, но несколько
отличающаяся реализация, в MySQL скобки
обязательны
UTC_DIFF () Функция SQL UTC_DATE ( ) , предоставляет возможность полу-
чить тот же результат, что и UTC_DIFF ()

VALUE() Функция SQL, псевдоним COALESCE ( ) , идентичнсый синтаксис


для COALESCE () и реализация
VARIANCE() Функция SQL VARIANCE ( ) , новая в MySQL 4.1.0

WEEKOFYEARO Функция SQL WEEKOFYEAR ( ) , новая в MySQL 4.1.1


А
Поиск и устранение
неполадок в программах
MySQL

В настоящем приложении перечислены некоторые наиболее часто встречающиеся


проблемы и сообщения об ошибках, с которыми вы можете столкнуться, работая с
программами MySQL. Здесь описывается, как определять причины проблем и как их
затем решать.

А.1. Как определить причину проблемы


Когда вы сталкиваетесь с проблемой, первое, что нужно сделать - определить, какая
именно программа или часть оборудования вызвали ее:
• Если вы наблюдаете один из следующих симптомов, вероятно, причина проблемы
кроется в оборудовании (таком как память, материнская плата, центральный про-
цессор или жесткий диск), или же в ядре операционной системы:
• Клавиатура не работает. Это легко проверить, нажав клавишу <Caps Lock>.
Если индикатор Caps Lock не реагирует, вам надо заменить клавиатуру.
(Прежде чем делать это, перезапустите компьютер и проверьте кабельное со-
единение.)
• Указатель мыши не двигается.
• Машина не отвечает на команду ping с удаленной машины.
• Другие программы, не относящиеся к MySQL, работают неправильно.
• Ваша система самопроизвольно перезапускается. (Ошибочные программы
пользовательского уровня никогда не смогут остановить систему.)
В этом случае начните с проверки всех кабельных соединений и запуска каких-
либо диагностических инструментов для проверки оборудования. Вам также сле-
дует проверить, нет ли каких-нибудь исправлений, обновлений или пакетов об-
новлений для операционной системы, которые могут решить возникшую пробле-
му. Убедитесь также, что все ваши системные библиотеки, подобные glibc, име-
ют самые новые версии.
А.1. Как определить причину проблемы 589

Всегда полезно использовать машину с ЕСС-памятью, чтобы обнаруживать на


ранней стадии проблемы, касающиеся памяти.
• Если ваша клавиатура заблокирована, возможно, вам удастся восстановить ее,
войдя в систему с другой машины и выполнив команду kbdjnode -a.
• Просмотрите системный журнальный файл (/var/log/messages или подобный) на
предмет нахождения причины проблем. Если вы предполагаете, что проблема в
MySQL, просмотрите также журнальные файлы MySQL. См. раздел 4.8.
• Если вы не думаете, что причина проблемы связана с оборудованием, вам нужно
найти, какая именно программа ее вызывает. Попробуйте воспользоваться top, ps,
диспетчером задач (Task Manager) или чем-то подобным, чтобы найти, какая про-
грамма захватывает процессор или блокирует машину.
• Используйте top, df или подобную программу, чтобы определить, не превышен
ли лимит объема памяти, дискового пространства, количества файловых дескрип-
торов или каких-нибудь других важных ресурсов.
• Если проблему вызвал какой-либо выполняющийся процесс, вы всегда можете
попробовать прервать его. Если это не удается, то видимо, это ошибка операци-
онной системы.
Если после того, как проверены все эти возможности, вы пришли к выводу, что про-
блему вызвал сервер MySQL или его клиентская программа, наступает время отправить
сообщение об ошибке в список рассылки или переслать его в нашу службу поддержки. В
отчете об ошибке постарайтесь дать как можно более детальное описание поведения
системы и того, что, по вашему мнению, происходит. Вы также должны указать, почему
считаете, что проблема вызвана MySQL. Рассмотрите все ситуации, описанные в данном
разделе. Установите точно, как проявляются проблемы, когда вы проверяете свою сис-
тему. С помощью копирования и вставки поместите в отчет все диагностические сооб-
щения программ и сообщений об ошибках из журнальных файлов.
Постарайтесь описать в деталях, какая программа не работает, и все наблюдаемые
вами симптомы. В прошлом мы получали много сообщений об ошибках, в которых со-
общалось, что "система не работает". Это не дает нам никакой информации о проблеме.
1. Если программа аварийно завершилась, всегда полезно знать следующую инфор-
мацию:
• Оставляет ли она за собой на диске образ памяти (core dump)?
• Не занимает ли она все время процессора? Проверьте это с помощью top. Дайте
возможность программе поработать достаточное время. Возможно, она просто
выполняет работу, требующую большой вычислительной мощности.
• Если проблемы вызывает сервер mysqld, можете ли вы получить от него ка-
кой-то отклик командами mysqladmin -u root ping ИЛИ mysqladmin -и root
processlist?
• Что сообщает клиентская лрограмма при попытке подключения к серверу
MySQL? (Например, попробуйте запустить mysql.) He зависает ли она? Можете
ли вы получить от нее какой-либо вывод?
Когда отправляете отчет об ошибке, следуйте правилам, приведенным в разделе
1.7.1.2.
590 Приложение А. Поиск и устранение неполадок в программах MySQL

А.2. Наиболее общие ошибки при работе


с программами MySQL
В этом разделе описываются некоторые ошибки, с которыми пользователи часто
сталкиваются при работе с программами MySQL. Несмотря на то что проблемы прояв-
ляются при работе клиентских программ, их решение может повлечь за собой изменение
конфигурации сервера MySQL.

А.2.1. Доступ запрещен


Ошибка Access denied (Доступ запрещен) может иметь множество причин. Часто
она имеет отношение к пользовательским учетным записям MySQL, которые сервер по-
зволяет использовать клиентским программам при подключении. См. раздел 4.4.8, а
также раздел 4.4.2.

А.2.2. Невозможно подключиться к [локальному]


серверу MySQL
Клиент MySQL на Unix может подключаться к серверу mysqld двумя разными спосо-
бами: используя файл сокета Unix, чтобы работать через файл в файловой системе (по
умолчанию /tmp/mysql.sock), или же используя протокол TCP/IP, который подключает-
ся через порт с определенным номером. Подключение через Unix-сокет работает быст-
рее, чем TCP/IP, но может применяться только в случае, если сервер и клиент работают
на одной машине. Файл Unix-сокета используется, если вы не указываете имя хоста или
не задаете специальное имя localhost.
Если сервер MySQL работает под управлением Windows 9x или Me, вы можете под-
ключаться только по TCP/IP. Если сервер функционирует в среде Windows NT, 2000,
или ХР и запущен с опцией —enable-named-pipe, вы также можете подключаться по
именованным каналам, если клиент выполняется на том же хосте, где работает сервер.
По умолчанию именем канала будет MySQL. Если вы не указываете имя хоста при под-
ключении к mysqld, клиент MySQL вначале пытается подключиться по именованному
каналу. Если это не удается, он подключается через порт TCP/IP. Вы можете принуди-
тельно использовать именованный канал, указав ' . ' в качестве имени хоста.
Появление ошибки (2002) Can't connect t o . . . (He удается подключиться к...)
обычно означает, что в системе нет работающего сервера MySQL, или же при попытке
подключения вы указали неправильный файл Unix-сокета или номер порта TCP/IP.
Начните с проверки того, присутствует ли mysqld в списке работающих процессов на
сервере хоста. (Для этого используйте ps под Unix или диспетчер задач под Windows).
Если такого процесса нет, нужно запустить сервер (см. раздел 2.4.4).
Если процесс mysqld функционирует, вы можете проверить его, попробовав перечис-
ленные ниже команды. Номер порта TCP/IP или имя Unix-сокета в вашей системе могут
отличаться; 1р_адрес_хоста представляет IP-адрес машины, на которой запущен сервер.
shell> mysqladmin version
shell> mysqladmin variables
shell> mysqladmin -h 'hostname4 version variables
shell> mysqladmin -h 'hostname4 —port=3306 version
shell> mysqladmin -h 1р_адрес_хоста version
shell> mysqladmin —protocol=socket —socket=/tmp/mysql.sock version
А.2. Наиболее общие ошибки при работе с программами MySQL 591

Обратите внимание на применение обратных кавычек с командой hostname. Это по-


зволяет вставить вывод команды hostname (представляющей имя данного хоста) в аргу-
менты команды mysqladmin.
Если у вас в системе нет команды hostname, или вы работаете под управлением
Windows, то можете вручную ввести имя хоста вашей машины (без кавычек) следом за
опцией -п. Вы также можете попробовать -h 127.0.0.1, чтобы подключиться через
TCP/IP к локальному хосту.
Ниже представлены некоторые причины появления ошибки Can' t connect to local
MySQL server (Невозможно подключиться к локальному серверу MySQL):
• Не запущен mysqld.
• Вы работаете в системе, использующей потоки MIT-pthreads. Если вы работаете в
системе, у которой нет встроенной поддержки потоков, MySQL использует пакет
MIT-pthreads. См. раздел 2.1.1. Однако не все реализации MIT-pthreads поддержи-
вают Unix-сокеты. На системах, где нет поддержки файлов Unix-сокетов, вы
должны всегда указывать явно имя хоста при подключении к серверу. Попробуй-
те следующую команду для проверки подключения:
shell> mysqladmin -h чhostname4 version
• Кто-то мог удалить файл Unix-сокета, который использует mysqld (по умолчанию
это /tmp/mysql. sock). Например, у вас может работать задание сгоп, которое уда-
ляет старые файлы из каталога /tmp. Вы всегда должны запускать команду
mysqladmin version, чтобы проверить, действительно ли существует файл сокета,
который mysqladmin будет использовать. Решение в этом случае сводится к изме-
нению задания сгоп таким образом, чтобы оно не удаляло mysql.sock, или к раз-
мещению упомянутого файла где-нибудь в другом месте. См. раздел А.4.5.
• Вы запустили mysqld с опцией —socket=/path/to/socket, но забыли указать кли-
ентским программам новое имя файла сокета. Если вы изменяете путь к файлу со-
кета для сервера, вы также должны известить об этом клиентов MySQL. Это мож-
но сделать той же опцией —socket при запуске клиентской программы. См. также
раздел А.4.5.
• Вы работаете под Linux, и один их потоков сервера прерван по ошибке (со сбро-
сом дампа памяти). В этом случае нужно прервать все остальные потоки mysqld
(например, командой k i l l или сценарием mysqlzap) прежде, чем перезапускать
сервер mysqld. См. раздел А.4.2.
• Сервер или клиентская программа могут не иметь необходимых прав доступа к
каталогу, в котором находится файл Unix-сокета, или же к самому файлу сокета.
В этом случае вы должны либо изменить права доступа к каталогу или файлу со-
кета таким образом, чтобы сервер и клиенты могли иметь к ним доступ, либо пе-
резапустить mysqld с опцией --socket, указывающей имя файла сокета, находя-
щегося в каталоге, в котором сервер сможет создать его и клиент будет иметь к
нему доступ.
Если вы получаете сообщение об ошибке Can' t connect to MySQL server on хост
(Невозможно подключиться к серверу MySQL на хост), можете попробовать проделать
следующие вещи, чтобы найти, в чем проблема:
592 Приложение А. Поиск и устранение неполадок в программах MySQL

• Проверьте, запущен ли сервер на хосте, выполнив команду t e l n e t хост 3306 и


несколько раз нажав клавишу <Enter>. (3306 - это порт по умолчанию, который
использует MySQL. Измените это значение, если ваш сервер прослушивает дру-
гой порт.) Если сервер MySQL работает и использует этот порт, то вы должны
получить ответ, который включает номер версии сервера. Если вы получите
ошибку вроде такой: t e l n e t : Unable to connect to remote host: Connection
refused (telnet: Невозможно подключиться к удаленному хосту: Подключение от-
клонено), то это означает, что на этом порте нет работающего сервера.
• Если сервер запущен на локальном хосте, попробуйте подключиться через файл
Unix-сокета с помощью команды mysqladmin -h localhost variables. Проверьте
номер порта TCP/IP, на который настроен сервер (это значение переменной port).
• Убедитесь, что ваш сервер mysqld не был запущен с опцией --skip-nrtworking-
service. Если эта опция использовалась, вы не сможете подключиться через
TCP/IP.

А.2.3. Клиент не поддерживает протокол аутентификации


MySQL 4.1 и выше, поддерживает протокол аутентификации, основанный на ал-
горитме хеширования паролей, который не совместим с тем, что используют старые
клиентские программы. Если вы обновили сервер до версии 4.1, то попытка подклю-
чения к нему более старыми клиентами может провалиться с выдачей следующего
сообщения:
shell> mysql
Client does not support authentication protocol requested
by server; consider upgrading MySQL client
Для решения этой проблемы воспользуйтесь одним из следующих подходов:
• Обновите все клиентские программы, чтобы они использовали клиентскую биб-
лиотеку от версии 4.1.1 или более новую.
• При подключении к серверу клиентскими программами более старых версий,
используйте учетную запись, для которой установлен пароль в формате старых
версий.
• Переустановите пароли для всех пользователей, которым нужно работать со ста-
рыми клиентскими программами таким образом, чтобы они были в старом фор-
мате. Это можно сделать с помощью оператора SET PASSWORD и функции
OLD_PASSWORD():
mysql> SET PASSWORD FOR
-> ' пользователь' @ ' хост' = OLD_J?ASSWORD (' новый_пароль') ;

В качестве альтернативного варианта используйте UPDATE и FLUSH PRIVILEGES:


mysql> UPDATE m y s q l . u s e r SET Password = OLD_PASSWORD('новый_пароль')
-> WHERE Host = 'хост* AND U s e r = 'пользователь1;
mysql> FLUSH PRIVILEGES;

Подставьте вместо новый^пароль новый пароль. MySQL не может сообщить вам,


какой пароль был установлен ранее, поэтому вам придется указать новый.
• Укажите серверу использовать старый алгоритм хеширования паролей:
А.2. Наиболее общие ошибки при работе с программами MySQL 593

1. Запустите mysqld с опцией --old-password.


2. Установите пароль в старом формате каждой учетной записи, пароль которой
был изменен под длинный формат 4.1. Вы можете идентифицировать эти
учетные записи с помощью следующего запроса:
mysql> SELECT Host, User, Password FROM mysql.user
-> WHERE LENGTH(Password) > 16;
Для каждой учетной записи, возвращенной этим запросом, используя значения
User и Host, присвойте пароль функцией OLDPASSWORDO вместе с оператором
SET PASSWORD или UPDATE, как было показано выше.
Дополнительные сведения о хешировании паролей и аутентификации можно найти в
разделе 4.4.9.

А.2.4. Пароль не принимается при интерактивном вводе


Клиентские программы MySQL выдают приглашение на ввод пароля, когда запуска-
ются с опциями —password или -р, после которых пароль не указавается:
shell> mysql -u имя_пользователя -р
Enter password:
В некоторых системах вы можете обнаружить, что пароль работает, когда он указан в
файле опций, или в командной строке, но не работает, когда вы вводите его интерактив-
но по приглашению Enter password:. Это случается, когда библиотека, представляемая
системой для чтения паролей, ограничивает при вводе его длину меньшим количеством
символов (обычно восемью). Это проблема системной библиотеки, а не MySQL. Чтобы
обойти это, измените пароли MySQL, чтобы они не превышали по длине 8 символов,
или же указывайте пароли в файле опций.

А.2.5. Хост йимя__хоста заблокирован


Если вы получаете приведенное ниже сообщение об ошибке, это означает, что mysqld
получил много запросов на подключение от хоста ' имя_хоста', которые были прерваны:
Host 'имя_хоста1 is blocked because of many connection errors.
Unblock with 'mysqladmin flush-hosts'
Хост 'имя хоста* заблокирован по причине множества ошибок подключений.
Разблокируйте хост с помощью 'mysqladmin flush-hosts'
Максимальное количество прерванных запросов на подключение определяется зна-
чением системной переменной max_connect_errors. После того, как max_connect_errors
попыток подключения проваливаются, сервер предполагает, что что-то не так (напри-
мер, что кто-то пытается его взломать), и блокирует все дальнейшие подключения до тех
пор, пока вы не выполните команду mysqladmin flush-hosts или оператор FLUSH HOSTS.
См. раздел 4.2.3.
По умолчанию mysqld блокирует хост после 10 ошибок подключения. Это можно из-
менить, запустив его следующим образом:
shell> mysqld_safe —max_connect_errors=10000 &
Если вы получаете это сообщение об ошибке для конкретного хоста, вам следует
проверить, все ли в порядке с подключением через TCP/IP с этого хоста. Если у вас
594 Приложение А. Поиск и устранение неполадок в программах MySQL

проблема с сетью, будет не слишком хорошо увеличивать значение переменной


max_connect_errors.

А.2.6. Слишком много подключений


Если при попытке подключения к mysqld вы получаете ошибку Too many connections
(Слишком много подключений), это означает, что все возможные подключения уже за-
няты другими клиентами.
Количество допустимых подключений управляется системной переменной
maxconnections. Ее значение по умолчанию равно 100. Если вам нужно поддерживать
больше подключений, перезапустите mysqld, указав большее значение этой переменной.
mysqld в настоящее время разрешает подключиться max_connections+l клиенту. До-
полнительное подключение зарезервировано для пользователя с привилегией SUPER. Вы-
давая привилегию SUPER только администраторам, а не обычным пользователям (кото-
рым она и не нужна), администратор всегда сможет подключиться к серверу и восполь-
зоваться SHOW PROCESSLIST для диагностики проблем, даже если максимальное
количество непривилегированных пользователей уже подключены.
Максимальное количество подключений, которое может поддерживать MySQL, за-
висит от качества библиотеки поддержки потоков на данной платформе. Linux или
Solaris в состоянии обеспечить 500-1000 параллельных подключений, в зависимости от
того, сколько памяти доступно в системе, и какую работу выполняют клиенты.

А.2.7. Недостаточно памяти


Если вы отправляете запрос, используя клиентскую программу mysql, и получаете
ошибку вроде приведенной ниже, это означает, что mysql не хватает памяти, чтобы со-
хранить весь результат запроса:
mysql: Out of memory at line 42, 'malloc.c 1
mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k)
ERROR 2008: MySQL client ran out of memory
Чтобы исправить положение, сначала убедитесь в корректности выданного запроса.
Имеет ли смысл то, что он возвращает настолько много строк? Если нет, исправьте за-
прос и попробуйте запустить его снова. Иначе можете вызвать mysql с опцией —quick.
Это заставит его использовать функцию С API mysql_use_result(), чтобы получать
больший по объему результат, который меньше нагружает клиента (но больше - сервер).

А.2.8. Сервер MySQL потерян


Этот раздел также касается ошибки Lost connection t o s e r v e r during query (По-
теряно соединение с сервером при обработке запроса). Наиболее общая причина ошибки
MySQL s e r v e r has gone away (Сервер MySQL потерян) связана с тем, что сервер закры-
вает соединения по тайм-ауту. В этом случае вы получите один из следующих кодов
ошибки (какой именно - зависит от операционной системы):
Код ошибки Описание
CR_SERVER_GONE_ERROR Клиент не смог отправить запрос серверу.
CR_SERVER_LOST Клиент не получил ошибку при записи на сервер, но и не
получил полного ответа (или ни одного ответа) на запрос.
А.2. Наиболее общие ошибки при работе с программами MySQL 595

По умолчанию сервер закрывает соединение после восьми часов простоя. Вы можете


изменить этот предел, установив нужное значение переменной wait_timeout при запус-
ке mysqld. См. раздел 4.2.3.
Если у вас есть сценарий, вам достаточно просто повторить запрос, чтобы произошло
автоматическое повторного подключение.
Эта ошибка также появиться в случае, если кто-то прервал поток, обслуживающий
соединение, с помощью оператора KILL или команды mysqladmin k i l l .
Другая общая причина появления ошибки MySQL server has gone away во время вы-
полнения клиентской программы состоит в том, что вы пытаетесь выполнить запрос по-
сле того, как закрыли соединение. Это свидетельствует о логической ошибке в програм-
ме, которую потребуется исправить.
Вы можете проверить, не был ли сервер остановлен и перезапущен, выполнив коман-
ду mysqladmin version и проверив время работы сервера. Если клиентское соединение
было прервано из-за того, что mysqld был прерван по ошибке и перезапущен, вам нужно
сосредоточиться на поиске причины останова mysqld. Начните с проверки того, не при-
водит ли ваш запрос к аварийному останову сервера. См. раздел А.4.2.
Эту ошибку можно также получить, прислав серверу неправильный или слишком
большой запрос. Если mysqld получает пакет, который слишком велик, или приходит не
в том порядке, он предполагает, что что-то идет неправильно и разрывает соединение.
Если вам нужно выполнять большие запросы (например, если вы работаете со столбца-
ми типа BLOB), можете увеличить предел запроса, установив новое значение серверной
переменной maxallowedpacket, которое по умолчанию составляет 1 Мбайт. Возможно,
вам придется также увеличить максимальный размер пакета на клиентской стороне. До-
полнительную информацию по установке размера пакета можно найти в разделе А.2.9.
Вы также получите разрыв подключения, если пошлете пакет размером в 16 Мбайт
или больше, если версия вашего клиента - ниже 4.0.8, а версия сервера - 4.0.8 или выше.
Если вы хотите составить отчет об ошибке, связанной с этой проблемой, не забудьте
включить в него следующую информацию:
• Укажите, прервалась ли работа сервера MySQL. Информацию об этом можно
найти в журнале ошибок сервера. См. раздел А.4.2.
• Если определенный запрос приводит к аварийному завершению mysqld и удале-
нию таблиц, которые проверялись непосредственно перед запросом с помощью
оператора CHECK TABLE, можете ли вы предоставить воспроизводимый тестовый
случай?
• Каково значение системной переменной wait_timeout? (Эту информацию выдаст
команда mysqladmin variables.)
• Пытались ли вы запускать mysqld с опцией —log, чтобы проверить, не появляется
ли проблемный запрос в журнале?
См. раздел 1.7.1.2.

А.2.9. Слишком большой пакет


Коммуникационный пакет - это отдельный SQL-оператор, отправленный серверу
MySQL, или отдельная строка, отправленная клиенту.
В MySQL 3.23 максимальный размер пакеты составлял 16 Мбайт, из-за ограничений,
накладываемых клиент-серверным протоколом. Начиная с MySQL 4.0.1, этот предел
составляет 1 Гбайт.
596 Приложение А. Поиск и устранение неполадок в программах MySQL

Когда клиент MySQL или сервер mysqld получает пакет размером больше, чем
max_allowedj?acket байт, он выдает ошибку Packet too large (Слишком большой па-
кет) и закрывает соединение. В некоторых клиентах в этом случае вы также можете по-
лучить сообщение об ошибке Lost connection to MySQL server during query (Потеря
соединения с сервером MySQL во время выполнения запроса).
И клиент, и сервер имеют свою собственную переменную max_allowed_packet, по-
этому если вы хотите работать с большими пакетами, то должны увеличить ее значение
как на клиенте, так и на сервере.
Если вы применяете клиентскую программу mysql, в ней по умолчанию
max_allowed_packet равно 16 Мбайт. Это также максимальное значение этой перемен-
ной, которое допускалось в версиях MySQL до 4.0. Чтобы установить большее значение
в версии 4.0 и выше, запускайте mysql следующим образом:
mysql> mysql —max_allowed_packet=32M
Это установит максимальный размер пакета в 32 Мбайт.
Значение по умолчанию max_allowed_packet для сервера равно 1 Мбайт. Вы можете
увеличить его, если серверу необходимо работать с большими запросами (например,
если вы работаете со столбцами BLOB). Например, чтобы установить значение перемен-
ной для сервера в 16 Мбайт, запускайте сервер так:
mysql> mysqld —max_allowedjpacket=16M
До версии MySQL 4.0 синтаксис был иной:
mysql> mysqld —set-variable=max_allowedjpacket=16M
Для установки значения max_allowed_packet можно также использовать файл опций.
Например, чтобы установить это значение в 16 Мбайт, добавьте в файл опций следую-
щие строки:
[mysqld]
max_allowed_packet=16M
До MySQL версии 4.0 синтаксис выглядел по-другому:
[mysqld]
set-variable = max_allowed_packet=16M
Увеличивать значение этой переменной вполне безопасно, потому что дополнитель-
ная память выделяется только по необходимости. Например, mysqld выделяет дополни-
тельную память, только когда получает длинный запрос, или когда должен вернуть
большую строку результата. Небольшое значение по умолчанию для этой переменной -
простая предосторожность, предусмотренная, чтобы перехватывать некорректные паке-
ты между клиентом и сервером, а также гарантировать, что не будет превышен размер
доступной памяти, если неожиданно будет переслан большой пакет.
Вы можете также столкнуться со странными проблемами больших пакетов, если ис-
пользуете большие значения BLOB, но не предоставляете mysqld памяти достаточного
объема для обработки этих запросов. Если вы предполагаете, что причина в этом, по-
пробуйте добавить ulimit -d 256000 в начало сценария mysqld_safe и перезапустите
сервер.
А.2. Наиболее общие ошибки при работе с программами MySQL 597

А.2.10. Ошибки связи и прерванные соединения


Журнал ошибок сервера - это полезный источник информации о проблемах подклю-
чений (см. раздел 4.8.1). Начиная с версии MySQL 3.23.40, если вы запускаете сервер с
опцией —warnings (или —log-warnings, начиная с MySQL 4.0.3), то вы можете найти в
журнале ошибок следующие сообщения:
010301 14:38:23 Aborted connection 854 to db: 'users' user: 'josh'
Если сообщение Aborted connection (Прерванное соединение) появляется в журнале
ошибок, причиной может быть одна из следующих:
• Клиентская программа не вызвала mysql_close () перед завершением.
• Клиент находился в неактивном состоянии дольше, чем wait_timeout или
interactive_timeout секунд, не передавая никаких запросов к серверу. См. раз-
дел 4.2.3.
• Клиентская программа прервалась внезапно, во время передачи данных.
Когда любое из этих событий происходит, сервер увеличивает значение переменной
состояния Aborted_clients.
Сервер увеличивает значение переменной Aborted_clients также в следующих
случаях:
• У клиента нет прав подключения к базе данных.
• Клиент указал неверный пароль.
• Коммуникационный пакет содержит неверную информацию.
• Получение пакета заняло больше, чем connect_timeout секунд времени. См. раз-
дел 4.2.3.
Если происходит что-то из упомянутого выше, возможно, кто-то пытается взломать
ваш сервер!
Ниже представлены другие причины проблем, связанных с прерванными клиентами
и прерванными соединениями:
• Используется Ethernet-протокол в Linux, как полудуплексный, так и полнодуп-
лексный. Многие драйверы Ethernet в Linux содержат эту ошибку. Вы можете
протестировать эту ошибку, пересылая огромный файл по FTP между клиентской
и серверной машинами. Если передача идет в режиме "рывок-пауза-рывок-пауза",
значит, вы столкнулись с синдромом дуплекса Linux. Единственным решением
будет переключение режима обеих сетевых плат, а также сетевых концентрато-
ров/коммутаторов в полнодуплексный режим, либо в полудуплексный, с после-
дующим тестированием результата, чтобы найти наилучшие установки.
• Возникла какая-то проблема с библиотекой поддержки потоков, которая является
причиной прерывания чтения.
• Неудачно настроен протокол TCP/IP.
• Повреждены сетевые платы, концентраторы, коммутаторы, кабели или тому по-
добное. Это можно проверить, только заменив сетевое оборудование.
• Значение переменной max_allowed_packet слишком мало, либо запросы требуют
больше памяти, чем отведено mysqld. См. раздел А.2.9.
598 Приложение А. Поиск и устранение неполадок в программах MySQL

А.2.11. Переполнение таблицы


Существует несколько причин появления ошибки переполнения таблиц:
• Вы работаете с сервером MySQL версии, более старой, чем 3.23 и временная таб-
лица, размещенная в памяти, разрослась до более чем tmp__table_size байт. Что-
бы избежать этой проблемы, можете указать опцию -0 tmp_table_size=#, чтобы
заставить mysqld увеличить размер временной таблицы, или использовать SQL-
оператор SQL_BIG_TABLES перед отправкой проблематичного запроса.
Вы также можете запускать mysqld с опцией —big-tables. Это абсолютно то же
самое, что и применение SQL_BIG_TABLES для всех запросов.
Начиная с MySQL 3.23, эта проблема возникать не должна. Если размещаемая в
памяти временная таблица становится больше tmp_table_size байт, сервер авто-
матически преобразует ее в таблицу My ISAM, размещаемую на диске.
• Вы применяете таблицы InnoDB и превысили объем места, отведенного в таблич-
ном пространстве InnoDB. См. раздел 9.8.
• Вы используете таблицы ISAM или My ISAM под управлением операционной систе-
мы, которая поддерживает файлы размером не более 2 Гбайт, и достигли этого
предела в каком-то из файлов индекса или данных.
• Вы применяете таблицы My ISAM, и пространство, необходимое для хранения ее
данных, превысило разрешенное размером внутреннего указателя. (Если вы не за-
даете опцию MAX_ROWS при создании таблицы, MySQL использует системную пе-
ременную myisam_data_pointer_size. Ее значения по умолчанию в 4 байта доста-
точно для работы с таблицами размером только в 4 Гбайт.) См. раздел 4.2.3.
Максимально допустимый размер файла данных или индекса можно проверить с
помощью следующего оператора:
SHOW TABLE STATUS FROM database LIKE 'имя_таблицы';
Вы также можете использовать myisamchk -dv /путь/к/файлу-индекса-таблицы.
Если размер указателя слишком мал, проблему можно решить с помощью ALTER
TABLE:
ALTER TABLE имя_таблицы MAX_ROWS=1000000000 AVG_ROW
Вы должны указывать AVGROWLENGTH только для таблиц со столбцами типа TEXT
или BLOB. В этом случае MySQL не может оптимизировать необходимое про-
странство, основываясь только на количестве строк.

А.2.12. Невозможно создать/записать файл


Если при выполнении некоторых запросов вы сталкиваетесь со следующим типом
ошибки, это означает, что MySQL не может создать временный файл для размещения
результирующего набора во временном каталоге:
Can't create/write to file !\\sqla3fe_0.ism'.
Это сообщение об ошибке типично для Windows, сообщение в Unix выглядит похо-
же. Для исправления запустите mysqld с опцией —tmpdir, или добавьте эту опцию в
раздел [mysqld] файла опций. Например, для указания каталога C:\temp используются
следующие строки:
А.2. Наиболее общие ошибки при работе с программами MySQL 599

[mysqld]
tmpdir=C:/temp
Каталог С: /temp должен уже существовать. См. раздел 3.3.2.
Проверяйте также код получаемой ошибки с помощью perror. Одной из причин, по
которой сервер не может записывать в таблицу, может быть переполнение файловой
системы:
shell> perror 28
Error code 28: No space left on device

A.2.13. Команды не синхронизированы


Если вы получаете сообщение об ошибке Commands out of sync; you can't run t h i s
command now (Команды не синхронизированы; вы не можете выполнить эту команду сей-
час) в клиентском коде, это означает, что клиентские функции вызывались в неверном
порядке.
Это может случиться, например, если вы используете mysql_use_result () и пытае-
тесь выполнить новый запрос до вызова mysql_free_result (). Это также может про-
изойти, если вы пытаетесь выполнить два запроса, возвращающие данные, без вызова
между ними mysql_use_result () или mysql_store_result ().

А.2.14. Игнорируется пользователь


Если вы получаете следующую ошибку, это означает, что когда mysqld запускается
или перезагружает таблицы привилегий, он находит в таблице user пользовательскую
учетную запись с неверным паролем:
Found wrong password for user: 'some_user'@'some_hostf; ignoring user
В следующем списке перечислены возможные причины и способы решения этой
проблемы:
• Возможно, вы запустили новую версию mysqld со старой таблицей user. Это
можно проверить, выполнив команду mysqlshow mysql user и проверив длину
столбца Password; она должны быть не меньше 16 символов. Если она короче,
нужно это исправить, запустив сценарий scripts/add_long_password.
• Учетная запись имеет старый пароль (длиной до 8 символов), a mysqld был за-
пущен без опции --old-protocol. Обновите пользовательскую учетную запись
в таблице user, присвоив ей новый пароль, или перезапустите mysqld с опцией
—old-protocol.
• Вы указали пароль в таблице user, не применяя функцию PASSWORD (). Используй-
те mysql для обновления пароля учетной записи в таблице user, не забыв приме-
нить функцию PASSWORD ():
x х
mysql> UPDATE user SET Password=PASSWORD( новый_пароль )
-> WHERE User='пользователь* AND Host='хост 1 ;

A.2.15. Таблица ' имя таблицы не существует


Если вы получаете любую из приведенных ниже ошибок, обычно это означает, что
таблица с указанным именем не существует в текущей базе данных:
600 Приложение А. Поиск и устранение неполадок в программах MySQL

Table 'имя^таблицы* doesn't exist


Can't find f i l e : 'имя_таблицы} (errno: 2)
В некоторых случаях это может означать, что таблица существует, но вы обращае-
тесь к ней некорректно:
• Поскольку MySQL использует каталоги и файлы для хранения баз данных и таб-
лиц, имена баз и таблиц чувствительны к регистру, если они располагаются в
файловых системах с зависящими от регистра именами файлов.
• Даже для файловых систем, в которых имена не зависят от регистра, таких как
Windows, все ссылки на данную таблицу в пределах запроса должны указываться
в одном регистре.
Для проверки, какие таблицы содержатся в текущей базе данных, используйте SHOW
TABLES.

А.2.16. Невозможно инициализировать набор символов


При возникновении проблема с набором символов вы можете получить такое сооб-
щение об ошибке:
MySQL Connection Failed: Can't i n i t i a l i z e character set имя_набора
Эта ошибка может возникать по следующим причинам:
• Набор символов является многобайтным, а поддержка этого набора на клиенте
отсутствует. В этом случае необходимо перекомпилировать клиенты, запустив
configure с опцией —with-charзеЬ=имя_набора или —with-extra-charsets=
имя_набора. См. раздел 2.3.2.
Все стандартные программы MySQL компилируются с —with-extra-charsets=
complex, что включает поддержку всех многобайтных символьных наборов. См.
раздел 4.7.1.
• Данный набор символов является простым, но не скомпилирован в mysqld, и фай-
лы определения наборов символов не найдены там, где клиент ожидал их найти. В
этом случае решить проблему можно одним из следующих способов:
• Перекомпилировать клиент с поддержкой требуемого набора символов. См.
раздел 2.3.2.
• Указать клиенту каталог, в котором находятся файлы определения символь-
ных наборов. Для большинства клиентов это можно сделать с помощью опции
—character-set-dir.

А.2.17. Файл не найден


Если вы получаете от MySQL сообщение ERROR ' . . . ' not found (errno: 23),
Can't open f i l e : . . . (errno: 24), или любую другую ошибку с кодом errno 23 или
errno 24, это означает, что MySQL не хватает файловых дескрипторов. Можно восполь-
зоваться perror, чтобы получить описание ошибки по ее номеру:
shell> perror 23
File table overflow
Переполнение таблицы файлов
А.З. Вопросы, связанные с установкой 601

shell> perror 24
Too many open f i l e s
Слишком много открытых файлов
shell> perror 11
Resource temporarily unavailable
Ресурс временно не доступен
Проблема заключается в том, что mysqld пытается открыть слишком много файлов
одновременно. Вы можете либо указать mysqld, чтобы он не открывал такого количества
файлов сразу, либо увеличить количество доступных ему файловых дескрипторов.
Чтобы указать mysqld, чтобы он не открывал одновременно так много файлов, можно
уменьшить размер табличного кэша, для этого уменьшив значение системной переменной
table_cache (ее значение по умолчанию равно 64). Уменьшение значения переменной
max_connections также уменьшит количество открытых файлов (по умолчанию - 100).
Для изменения количества доступных серверу файловых дескрипторов можно вос-
пользоваться опцией —open-files-limit mysqld_safe, или же (начиная с MySQL
3.23.30) установить системную переменную open_files_limit. См. раздел 4.2.3. Самый
простой способ установить эти значения - добавить их в файл опций. См. раздел 3.3.2.
Если у вас старая версия mysqld, которая не поддерживают установку предельного числа
открытых файлов, вы можете отредактировать сценарий mysqld_safe. В нем есть заком-
ментированная строка ulimit -n 256. Вы можете удалить символ '#', сняв тем самым
комментарий, и изменить число 256, указав необходимое число файловых дескрипторов,
доступных mysqld.
—open-files-limit и ulimit могут увеличить количество файловых дескрипторов,
но только в пределах, установленных операционной системой. Существует также "жест-
кий" лимит, который можно превысить, только если вы запустите mysqld_safe или
mysqld от имени пользователя root (только помните, что вам также нужно будет при
запуске сервера указывать опцию —user, чтобы он не продолжал работать от имени
root после своего запуска). Если вам понадобится увеличить лимит доступных каждому
процессу файловых дескрипторов, установленный операционной системой, проконсуль-
тируйтесь с документацией по системе.
^ На заметку!
r
rl Если вы работаете с оболочкой t c s h , u l i m i t работать не будет! Эта оболочка также даст не-
|| корректный результат, если вы запросите текущие значения лимитов. В этом случае вам следует
Ц запускать mysqld_saf e из sh.

А.З. Вопросы, связанные с установкой


А.3.1. Проблемы компоновки клиентской
библиотеки MySQL
Во время компоновки прикладной программы с клиентской библиотекой MySQL вы
можете получить ошибки неразрешенных ссылок для символов, начинающихся с
mysql_, подобные приведенным ниже:
/tmp/ccFKsdPa.o: In function N main f :
/tmp/ccFKsdPa.o(.text+Oxb): undefined reference to 4 mysql_init f
/tmp/ccFKsdPa.o(.text+0x31): undefined reference to 4 mysql_real_connect'
602 Приложение А. Поиск и устранение неполадок в программах MySQL

/tmp/ccFKsdPa.o (,t.ext+0x57) : undefined reference to N mysql_real_connect'


/tmp/ccFKsdPa.o(.text+0x69): undefined reference to 4 mysql_error'
/tmp/ccFKsdPa.o(.text+0x9a): undefined reference to 4 mysql_close'
Решить эту проблему можно, добавив -Ькаталог -Imysqlclient в конец команды
компоновки, где каталог представляет путь к каталогу, в котором находится клиентская
библиотека. Чтобы определить правильное значение пути, попробуйте такую команду:
shell> mysql_config —libs
Вывод mysqi__config может включать другие библиотеки, которые также должны
быть указаны в команде компоновки.
Если вы получаете сообщения undefined reference, касающиеся функций uncompress
или compress, добавьте в конец команды компоновки опцию -lz и попробуйте выдать ее
заново.
Если вы получаете сообщения undefined reference о функциях, которые должны
присутствовать в вашей системе, таких как connect, просмотрите страницы руководства
по функциям, чтобы найти, какие библиотеки должны быть включены во время компо-
новки.
Вы можете получить ошибки undefined reference для функций, которые отсутст-
вуют в вашей системе:
mf_format.о(.text+0x201) : undefined reference to ч l x s t a t 1
Обычно это означает, что ваша клиентская библиотека MySQL была скомпилирована
в системе, которая не на 100% совместима с вашей. В этом случае вам потребуется за-
грузить самый последний исходный дистрибутив MySQL и скомпилировать его само-
стоятельно. См. раздел 2.3.
Вы можете получить ошибки неразрешенных ссылок во время выполнения, когда
попытаетесь запустить программу MySQL. Если эти ошибки указывают на символы,
начинающиеся с mysql_, или же сообщают о том, что не может быть найдена библиотека
mysqlclient, это означает, что ваша система не может найти библиотеку общего исполь-
зования libmysqlclient.so. Чтобы исправить это, нужно указать системе, где конкретно
искать эту библиотеку. Воспользуйтесь любым из приведенных ниже методов, который
наиболее точно соответствует ситуации в вашей системе:
• Добавьте путь к каталогу, в котором находится libmysqlclient.so, в системную
переменную LD_LIBRARY_PATH.
• Добавьте путь к каталогу, в котором находится libmysqlclient.so, в системную
переменную LD_LIBRARY.
• Скопируйте libmysqlclient.so в один из каталогов, в которых система выполня-
ет поиск, такой как /lib, и обновите информацию о разделяемых библиотеках,
выполнив команду ldconf ig.
Другой способ решения этой проблемы сводится к статической компоновке либо к
удалению динамических библиотек перед началом компоновки вашего кода. Прежде
чем использовать второй вариант, вы должны убедиться, что никакие другие программы
не используют динамические библиотеки.
А.З. Вопросы, связанные с установкой 603

А.3.2. Как запускать MySQL от имени обычного


пользователя
Начиная с версий MySQL 4.0.17 и 4.1.2, в Windows можно запускать сервер в виде
системной службы от имени обычной пользовательской учетной записи. (Более старые
версии требовали наличия прав администратора. Это была ошибка, обнаруженная в
MySQL 3.23.54.)
В среде Unix MySQL-сервер mysqld может быть запущен любым пользователем. Од-
нако, из соображений безопасности, вы должны избегать запуска сервера от имени поль-
зователя Unix root. Для того чтобы запускать mysqld от обычного непривилегированно-
го пользователя имя_пользователя, потребуется предпринять следующие действия:
1. Если сервер работает, остановите его (с помощью mysqladmin shutdown).
2. Измените каталоги и файлы базы данных таким образом, чтобы учетная запись
имя_пользователя имела права чтения и записи в них (возможно, это придется
сделать от имени root):
shell> chown -R имя^пользователя /'путь/к/mysql/'каталог_данных
Если этого не сделать, сервер не сможет получить доступ к базе данных и ее таб-
лицам, если будет запущен от имени имя_пользователя.
Если каталоги или файлы внутри каталога данных MySQL являются символиче-
скими ссылками, те же изменения потребуется выполнить по отношению к ката-
логам и файлам, на которые они указывают, chown -R может не следовать за сим-
волическими ссылками.
3. Запустите сервер от имени имя_пользователя. Если вы работаете в версии
MySQL 3.22 или более поздней, альтернативой может быть запуск от имени
root, но с опцией —изег=имя_пользователя. Сервер mysqld стартует, а затем,
прежде чем принимать клиентские соединения, переключится на работу от име-
ни имя_полъзователя.
4. Чтобы запустить сервер автоматически во время запуска системы от имени задан-
ного пользователя, укажите имя пользователя, добавив опцию user в группу
[mysqld] файла опций /etc/my.cnf или файла my.cnf в каталоге данных сервера.
Например:
[mysqld]
мвет-имя_пользователя
Если ваша Unix-машина сама по себе недостаточно защищена, вы должны назначить
пароль учетной записи MySQL с именем root в таблицах привилегий. В противном слу-
чае любой пользователь, зарегистрированный в системе, сможет запускать клиентскую
программу mysql с опцией —user=root и выполнять любые операции. (Присвоить паро-
ли всем пользователям MySQL - в любом случае хорошая идея, но особенно это важно,
если на хосте сервера зарегистрированы другие пользователи.) См. раздел 2.4.

А.3.3. Проблемы с правами доступа к файлам


Если у вас возникли проблемы с правами доступа к файлам, вероятно, переменная окру-
жения UMASK была установлена неправильно, когда стартовал сервер mysqld. Например,
MySQL может выдавать следующее сообщение, когда вы пытаетесь создать новую таблицу:
604 Приложение А. Поиск и устранение неполадок в программах MySQL

ERROR: Can't find f i l e : 'путь/к/имя_файла.frm' (Errcode: 13)


Значение UMASK по умолчанию равно 0660. Это можно изменить, запуская
mysqld_safe следующим образом:
shell> UMASK=384 # = 600 восьмеричное
shell> export UMASK
shell> mysqld_safe &
По умолчанию MySQL создает базы данных и RAID-каталоги со значением прав
доступа 0700. Подобное поведение можно изменить с помощью переменной UMASK_DIR.
Если это сделать, новые каталоги создаются с правами, устанавливаемыми комбинацией
переменных UMASK и UMASK_DIR. Например, если вы хотите предоставить групповой дос-
туп ко всем новым каталогам, то можете поступить так:
shell> UMASK_DIR=504 # = 770 восьмеричное
shell> export UMASKJHR
shell> mysqld__safe &
В MySQL 3.23.25 и выше сервер предполагает, что значения UMASK и UMASK_DIR ука-
заны в восьмеричной форме, если они начинаются с нуля.
См. приложение Б.

А.4. Вопросы, касающиеся администрирования


А.4.1. Как сбросить пароль для root
Если вы не устанавливали пароль для root в MySQL, сервер вообще не будет запра-
шивать пароль при подключении от имени пользователя root. Однако настоятельно ре-
комендуется устанавливать пароли каждой пользовательской учетной записи (см. раздел
4.3.1).
Если вы использовали пароль root ранее, но забыли его, можете установить новый
пароль. Следующая процедура описывает этот процесс для среды Windows. Процедуру
для Unix можно найти далее в настоящем разделе.
Процедура для Windows.
1. Войдите в систему как Administrator (Администратор).
2. Остановите сервер MySQL, если он работает. Для сервера, запущенного как сис-
темная служба Windows, активизируйте диспетчер служб (Service manager):
S t a r t s Control Panel^AdministratJve Tools^Services (Пуск^ Панель управле-
ния^ Администрирование •=> Службы).
Затем найдите службу MySQL и остановите ее. Если сервер запущен не в виде
системной службы, можно воспользоваться диспетчером задач, чтобы его
остановить.
3. Откройте окно консоли:
c c c c
Start >Run t>cmd(Пycк >Bыпoлнить >cmd).
4. Предполагается, что MySQL установлен в каталоге С: \mysql. Если вы установили
его в другой каталог, внесите соответствующие изменения. В командной строке
DOS выполните команду:
С:\> C:\mysql\bin\mysqld-nt --skip-grant-tables
А.4. Вопросы, касающиеся администрирования 605

Это запустит сервер в специальном режиме, который не проверяет таблицы при-


вилегий для управления доступом.
5. Оставив первое окно консоли открытым, откройте второе окно консоли и выпол-
ните в нем следующие команды (вводя каждую в отдельной строке):
С:\> C:\mysql\bin\mysqladmin -u root
flush-privileges password "новый_пароль"
С:\> C:\mysql\bin\mysqladmin -и root -р shutdown
Замените 'новый_пароль* реальным паролем, который хотите использовать. Вто-
рая команда выдаст приглашение на ввод нового пароля. Введите тот же пароль,
который был указан в первой команде.
6. Остановите сервер MySQL, затем перезапустите его в нормальном режиме. Если
вы запускаете сервер как системную службу, запустите его из окна Windows
Services (Службы Windows). Если вы запускаете сервер вручную, используйте
команды, с помощью которых обычно это делаете.
7. Теперь вы должны быть готовы подключаться с новым паролем.
В среде Unix процедура переустановки пароля для root выглядит следующим образом:
1. Войдите в систему как пользователь root или же пользователь, от имени которого
запускается сервер mysqld.
2. Найдите файл .pid, который содержит идентификатор процесса сервера. Точное
местоположение и имя этого файла зависит от вашего дистрибутива, имени хоста
и конфигурации. Обычно он находится в /var/lib/mysql/, /var/run/mysqld/ или
/usr/local/mysql/data/. Как правило, расширением этого файла является .pid, a
имя начинается либо с mysql, либо с имени вашего хоста.
Теперь вы можете остановить сервер MySQL, послав сигнал командой k i l l (но не
k i l l -9) процессу mysqld, используя путь файла .pid, в следующей команде:
shell> k i l l "cat /каталог-данных-тузд1/имя_хоста.<р1й*
Обратите внимание на использование обратных кавычек вместо прямых для ко-
манды cat. Это подставит ее вывод в качестве аргумента команды k i l l .
3. Перезапустите сервер MySQL со специальной опцией —skip-grant-tables:
shell> mysqld_safe —skip-grant-tables &
4. Установите новый пароль для учетной записи MySQL root@localhost:
shell> mysqladmin -u root flush-privileges password " новый_пароль"
Замените "новый_пароль " реальным паролем, который хотите использовать.
5. Остановите сервер MySQL, затем перезапустите его в нормальном режиме.
6. Теперь вы должны быть готовы подключаться с новым паролем.
В качестве альтернативы на любой платформе вы можете установить новый пароль, с
помощью клиентской программы mysql:
1. Остановите mysqld и перезапустите его с опцией —skip-grant-tables, как опи-
сано выше.
2. Подключитесь к серверу по команде:
shell> mysql -u root
606 Приложение А. Поиск и устранение неполадок в программах MySQL

3. Выполните следующий оператор внутри клиента mysql:


mysql> UPDATE mysql.user SET Password=PASSWORD ('новый_пароль')
-> WHERE U s e r = ' r o o t ' ;
mysql> FLUSH PRIVILEGES;
Замените 'новый_пароль реальным паролем, который хотите использовать.
4. Остановите сервер MySQL, затем перезапустите его в нормальном режиме.
5. Теперь вы должны быть готовы подключаться с новым паролем.

А.4.2. Что делать, если MySQL терпит крах


Каждая версия MySQL перед выходом тестируется на множестве платформ. Это не
гарантирует полного отсутствия ошибок, но если ошибки есть, то очень немного, и их
довольно-таки трудно найти. Если вы столкнулись с проблемой, то всегда полезно разо-
браться, что именно привело вашу систему к краху, поскольку в этом случае вы имеете
гораздо лучшие шансы быстро получить решение проблемы.
Первое, что следует сделать - разобраться, завершается ли аварийно сервер mysqld,
или проблема связана с клиентом. Вы можете проверить, насколько долго работает сер-
вер mysqld, с помощью команды mysqladmin version. Если mysqld аварийно прекратил
работу и был перезапущен, то имеет смысл поискать причину в журнале ошибок сервера
(см. раздел 4.8.1).
В некоторых системах в журнале ошибок можно найти трассировку стека на мо-
мент аварийного завершения mysqld и его можно проанализировать программой
resolve_stack_dump. Имейте в виду, что значения переменных, зафиксированные в жур-
нале ошибок, могут быть не на 100% верными.
Многие случаи краха сервера вызваны повреждением файлов данных или индексных
файлов. MySQL обновляет файлы на диске системным вызовом write () после каждого
SQL-оператора и перед тем, как известить клиента о результате. (Это не так, если вы
работаете с опцией —delay-key-write; в этом случае данные сразу записываются, а ин-
дексные файлы нет.) Это означает, что содержимое файлов данных будет в безопасно-
сти, даже если mysqld потерпит крах, потому что операционная система гарантирует,
что все несброшенные данные будут записаны на диск. Вы можете заставить MySQL
сбрасывать на диск данные после каждого SQL-оператора, запустив mysqld с опцией
— flush.
Исходя из вышесказанного, можно сделать вывод, что вы никогда не получите по-
врежденных таблиц, если только не случится что-то из следующего:
• Сервер MySQL или хост сервера был прерван в процессе обновления данных.
• Вы нашли ошибку в mysqld, которая приводит к его аварийному завершению в
процессе обновления данных.
• Некая внешняя программа манипулировала файлами данных или индексными
файлами одновременно с mysqld, не устанавливая правильно блокировки таблиц.
• Вы запустили несколько серверов mysqld, используя один и тот же каталог дан-
ных в системе, которая не поддерживает качетсвенных блокировок файловой сис-
темы (обычно управляемых диспетчером блокировок lockd), или же вы запустили
несколько серверов mysqld с опцией —skip-external-locking.
А.4. Вопросы, касающиеся администрирования 607

• У вас есть запорченный файл данных или индексный файл, который содержит по-
врежденные данные, которые сбивают с толку mysqld.
• Вы нашли ошибку в коде сохранения данных. Такое маловероятно, но это по-
следнее, что можно предположить. В этом случае вы можете попробовать изме-
нить тип таблиц для использования другого механизма хранения, выполнив опе-
ратор ALTER TABLE на восстановленной копии таблицы.
Поскольку иногда очень трудно понять причину краха, прежде всего проверьте, есть
ли вещи, которые работают у других, но приводят к краху вашу систему. Пожалуйста,
попробуйте следующее:
• Остановите mysqld командой mysqladmin shutdown, запустите myisamchk —silent
— force */* .MY I из каталога данных, чтобы проверить все таблицы My ISAM, и пе-
резапустите mysqld. Это гарантирует, что вы начинаете из чистого состояния. См.
главу 4.
• Запустите mysqld с опцией --log и попробуйте среди информации, записанной в
журнале, найти конкретный запрос, который приводит к аварии сервера. Около
95% всех ошибок связаны с конкретным запросом. Обычно это будет один из по-
следних запросов в файле протокола - непосредственно перед перезапуском сер-
вера. См. раздел 4.8.2. Если один и тот же запрос повторно прерывает работу сер-
вера, даже если вы проверили все занятые в нем таблицы непосредственно перед
его выполнением, вы сможете найти ошибку и составить отчет о ней. См. раздел
1.7.1.3.
• Попытайтесь составить тестовый случай, которым мы сможем воспользоваться
для воспроизведения проблемы.
• Попробуйте запустить тесты из каталога mysql-test. Они достаточно хорошо тес-
тируют функционирование MySQL. Вы можете добавить код в тесты производи-
тельности, который будет эмулировать ваше приложение. Тесты производитель-
ности можно найти в каталоге sql-bench исходного дистрибутива, или, для би-
нарного дистрибутива - в каталоге sql-bench вашей установки MySQL.
• Попробуйте запустить сценарий fork_big.pl (он находится в каталоге t e s t s ис-
ходного дистрибутива).
• Если вы настроили MySQL для отладки, будет гораздо легче собрать информа-
цию о возможных ошибках, если что-то идет не так. Настройка MySQL для от-
ладки включает безопасный распределитель памяти, который может найти не-
которые ошибки. Это также приводит к генерации большого объема выходной
информации о том, что происходит. Переконфигурируйте MySQL с помощью
опций —with-debug или —with-debug=full сценария configure и затем пере-
компилируйте MySQL.
• Проверьте, установлены ли все последние исправления для операционной системы.
• Используйте опцию —skip-external-locking с mysqld. В некоторых системах
диспетчер блокировок lockd работает некорректно. Опция —skip-external-
locking указывает mysqld не использовать внешнюю блокировку. (Это означает,
что вы не можете запустить два и более экземпляра mysqld на одном и том же ка-
талоге данных, и что нужно быть осторожным при использовании myisamchk. Не-
смотря на это, может быть поучительно попробовать эту опцию в качестве теста.)
608 Приложение А. Поиск и устранение неполадок в программах MySQL

• Пробовали ли вы mysqladmin -u root processlist, когда случилось так, что


mysqld работает, но не отвечает на запросы? Иногда mysqld вовсе не находится в
"коматозном" состоянии, даже если вам может так показаться. Проблема может
быть в том, что все соединения заняты, или могут возникнуть некоторые пробле-
мы внутренних блокировок, mysqladmin -u root processlist обычно в СОСТОЯ-
НИИ установить соединения даже в подобных случаях и предоставить полезную
информацию о количестве текущих подключений и их состоянии.
• В отдельном окне запустите команду mysqladmin -i 5 status или mysqladmin -i
5 -r status, чтобы получить статистическую информацию, пока работают дру-
гие запросы.
• Попробуйте предпринять следующие действия:
1. Запустите mysqld из gdb (или другого отладчика).
2. Запустите ваши тестовые сценарии.
3. Распечатайте трассировку вызовов и состояния локальных переменных на трех
самых низких уровнях. В gdb это можно сделать с помощью приведенных
ниже команд, когда mysqld потерпит крах внутри gdb:
backtrace
info local
up
info local
up
info local
С помощью gdb можно также проверить, какие существуют потоки, командой
info threads и переключиться на конкретный поток посредством команды
thread #, где # - идентификатор потока.
• Попытайтесь смоделировать приложение с помощью Perl-сценария, чтобы при-
вести mysqld к краху или неправильному поведению.
• Пришлите нормальный отчет об ошибке (см. раздел 1.7.1.3). Опишите ситуацию
даже более детально, нежели обычно. Поскольку MySQL работает у многих поль-
зователей, причиной краха может быть нечто такое, что есть только на вашем
компьютере (например, ошибка, связанная с вашими специфическими системны-
ми библиотеками).
• Если вы имеете проблемы с таблицами, содержащими строки динамической дли-
ны, и пользуетесь только столбцами VARCHAR (не BLOB и не TEXT), то можете по-
пробовать сменить тип этих столбцов с VARCHAR на CHAR с помощью оператора
ALTER TABLE. Это заставит MySQL использовать строки фиксированной длины.
Такие строки занимают немного больше места, но гораздо более устойчивы к по-
вреждениям.
Используемый в настоящее время код, работающий с динамическими строками,
применяется компанией MySQL AB в течение нескольких лет с очень небольшим
количеством проблем, однако строки динамической длины по своей природе в
большей степени подвержены ошибкам, поэтому имеет смысл попробовать такую
стратегию и посмотреть, поможет ли это.
А.4. Вопросы, касающиеся администрирования 609

А.4.3. Как MySQL обрабатывает переполнение диска


Когда случается переполнение диска, MySQL работает так:
• Проверяет ежеминутно, не появилось ли свободное пространство, чтобы записать
текущую строку; если место появляется, продолжает работу так, будто ничего не
случилось.
• Каждые шесть минут записывает в файл протокола сообщение о переполнении
диска.
Чтобы облегчить последствия проблемы, вы можете предпринять следующие шаги:
• Для продолжения работы потребуется только освободить достаточное простран-
ство на диске, чтобы вставить все строки.
• Чтобы прервать исполнение потока, необходимо использовать mysqladmin k i l l .
Поток будет остановлен в тот момент, когда следующий раз проверит наличие
места на диске (в пределах одной минуты).
• Остальные потоки могут пребывать в состоянии ожидания таблицы, которая при-
вела к переполнению диска. Если у вас несколько "заблокированных" потоков,
прерывание одного из них, который ожидает освобождения места на диске, может
позволить остальным продолжить работу.
Исключениями из описанного могут быть случаи, когда вы применяете REPAIR TABLE
или OPTIMIZE TABLE, или когда индексы создаются в пакетном режиме после выполне-
ния операторов LOAD DATA INFILE или ALTER TABLE. Все эти операторы могут создавать
огромные временные файлы, и если их предоставить самим себе, то они могут стать при-
чиной крупных проблем для всей остальной системы. Если диск переполняется в то
время, когда MySQL выполняет одну их этих операций, он удалит временный файл и
пометит таблицу как поврежденную. Исключением является только оператор ALTER
TABLE, который оставит старую таблицу без изменений.

А.4.4. Где MySQL хранит временные файлы


MySQL читает значение переменной окружения TMPDIR и трактует его как путь к ка-
талогу, в котором следует создавать временные файлы. Если переменная TMPDIR не уста-
новлена, MySQL использует каталоги по умолчанию операционной системы. Обычно
это /tmp, /var/tmp или /usr/tmp. Если каталог ваших временных файлов слишком мал,
вы можете воспользоваться опцией mysqld — tmpdir, чтобы указать каталог в вашей
файловой системе с достаточным свободным местом.
Начиная с MySQL 4.1, эта опция может включать в себя список нескольких путей,
используемых в циклическом порядке. Пути должны разделяться символом " : " в Unix
или " ; " в Windows, NetWare или OS/2.

S На заметку!
Ji Чтобы разделить эффективно нагрузку, эти пути должны указывать на каталоги, расположенные
Q на разных физических дисках, а не в разделах одного и того же диска.

Если сервер MySQL функционирует в качестве подчиненного в системе репликации,


вы не должны устанавливать опцию --tmpdir так, чтобы она указывала на каталог фай-
ловой системы, находящейся в памяти, либо на каталог, который автоматически очища-
ется при перезапуске компьютера. Подчиненный сервер репликации нуждается во вре-
610 Приложение А. Поиск и устранение неполадок в программах MySQL

менных файлах для обслуживания перезапуска таким образом, чтобы иметь возмож-
ность реплицировать временные таблицы или операции LOAD DATA INFILE. Если содер-
жимое каталога временных файлов будет потеряно при перезапуске сервера, репликация
перестанет работать.
Все временные файлы MySQL создает как скрытые. Это гарантирует, что они будут
удалены, если работу mysqld будет прервана. Неудобство в применении скрытых файлов
заключается в том, что вы не увидите большого временного файла, который переполнит
файловую систему в каталоге, в котором он расположен.
При выполнении сортировок (ORDER BY или GROUP BY) MySQL обычно использует
один или два временных файла. Максимально необходимый объем дискового простран-
ства в этом случае вычисляется по следующему выражению:
(длина сортируемых строк + sizeof{указатель на строку))
* количество совпадающих строк
*2
Размер указателя на строку обычно составляет 4 байта, но в будущем может вырасти
для работы с очень большими таблицами.
Для некоторых операторов SELECT MySQL также создает временные таблицы. Они не
скрыты и получают имена SQL_*.
ALTER TABLE создает временную таблицу в том же каталоге, где находится исходная
таблица.

А.4.5. Как защитить или изменить файл сокета MySQL


/tmp/mysql.sock
По умолчанию файл сокета Unix, который используется сервером при взаимодейст-
вии с локальными клиентами, расположен в /tmp/mysql.sock. Это может стать причи-
ной проблем, поскольку в некоторых версиях Unix удалять файлы из каталога tmp раз-
решено всем.
В большинстве версий Unix, однако, удалить временный файл в каталоге /tmp может
только тот, кто его создал, либо пользователь root. Чтобы включить это, установите бит
sticky для каталога /tmp, войдя в систему как root и выдав следующую команду:
shell> chmod +t /tmp
Вы можете проверить, установлен ли этот бит, с помощью команды Is -Id /tmp. Ес-
ли последним символом в правах доступа является t, значит бит установлен.
Другой подход предполагает изменение каталога, в котором сервер создает файл
Unix-сокета. Если вы сделаете это, то должны будет известить об этом все клиентские
программы. Местоположение этого файла можно указать разными способами:
• Указать путь в глобальном или локальном конфигурационном файле. Например,
поместите в /etc/my.cnf следующие строки:
[mysqld]
socket=/path/to/socket
[client]
socket=/path/to/socket
• Указывайте опцию —socket в командной строке mysqldsaf e, а также при запус-
ке клиентских программ.
А.4. Вопросы, касающиеся администрирования 611

• Установите в переменной окружения MYSQL_UNIX_PORT путь к файлу Unix-сокета.


• Перекомпилируйте MySQL из исходных текстов, чтобы использовать другое ме-
стоположение файла сокета по умолчанию. Определите путь в опции —with-
unix-socket-path во время запуска сценария configure. См. раздел 2.3.2.
Чтобы проверить, работает ли файл сокета в новом месте, попытайтесь подключиться
к серверу с использованием команды:
shell> mysqladmin —soctet=/путь/к/фаРшу_сокетa version

А.4.6. Проблемы с временными зонами


Если у вас возникла проблема с SELECT NOW (), возвращающим время GMT, а не ваше
локальное время, вам следует известить сервер о конкретной временной зоне. То же са-
мое касается случая, когда UNIX_TIMESTAMP() возвращает неверное значение. Это долж-
но быть сделано в окружении, в котором запущен сервер, например, в mysqldsafe или
mysql. server. См. приложение Б.
Установить временную зону для сервера можно с помощью опции —timezone=
имя_временной_зоны сценария mysqldsafe. Также ее можно задать в переменной окру-
жения TZ перед запуском mysqld. Допустимые значения опции и переменной окружения
зависят от системы. Проконсультируйтесь с документацией по операционной системе,
чтобы узнать, какие значения допускаются.
Б
Переменные
окружения

В настоящем приложении перечислены переменные окружения, которые явно или


неявно используются MySQL. Большинство из них упоминается в других разделах
настоящего руководства.
Следует отметить, что любые опции командной строки всегда имеют преимущество
перед значениями, указанными в переменных окружения. Опции, заданные в конфигу-
рационных файлах, также имеют преимущество перед значениями этих переменных.
Во многих случаях для изменения поведения MySQL предпочтительнее использовать
файлы опций вместо переменных окружения. См. раздел 3.3.2.
Таблица Б.1. Переменные окружения
Переменная Описание
схх Имя компилятора C++ (для запуска configure).
ее Имя компилятора С (для запуска configure).
CFLAGS Флаги компилятора С (для запуска configure).
CXXFLAGS Флаги компилятора C++ (для запуска configure).
DBIJJSER Имя пользователя по умолчанию для Perl DBI.
DBI_TRACE Опции трассировки для Perl DBI.
НОМЕ Путь по умолчанию к файлу хронологии mysql указывается как
$НОМЕ/.mysql_history.
LD_RUN_PATH Используется для указания местоположения библиотеки
libmysqlclient.so.
MYSQL_DEBUG Опции трассировки во время отладки.
MYSQLJilSTFILE Путь к файлу хронологии mysql; переназначает путь по умолчанию
$НОМЕ/.mysql_history.
MYSQL_HOST Имя хоста по умолчанию, используемое клиентской программой ко-
мандной строки mysql.
MYSQL PS1 Приглашение командной строки в клиентской программе mysql.
Приложение Б. Переменные окружения 613

Окончание табл. Б. 1

Переменная Описание
MYSQL_ PWD Пароль по умрлчанию для подключения к серверу raysqld. Имейте в
виду, что его использование небезопасно! См. раздел 4.5.6.
MYSQL_ TCP_PORT Значение по умолчанию номера порта TCP/IP.
MYSQL_UNIX_PORT Значение по умолчанию имени файла сокета Unix; используется для
подключения локальных клиентов.
PATH Используется оболочкой для поиска программ MySQL.
TMPDIR Каталог временных файлов.
TZ Наименование локальной временной зоны. См. А.4.6.
UMASK_ DIR Маска прав доступа к пользовательским каталогам; используется при
их создании.
UMASK Маска прав доступа к пользовательским файлам.
USER Имя пользователя по умолчанию в Windows и NetWare? применяемое
для подключения к серверу raysqld.
Предметный указатель

API-интерфейс, 19; 20; 31; 68; 158; 163; 165; Атомарная операция, 62
268; 536; 537
Б
G Библиотека
GnuPG, 90-92 readline,32; 104; 107; 132; 190; 191; 467
GPL, См. Лицензия GNU General Public regexp, 32; 45; 493
License, 18; 29; 32-34; 36; 39; 56; 141; 506;
524;582
В
Взаимная блокировка, 47; 70; 388; 432; 532;
557-560
innodb_additional_mem_pool_size, 236; 527;
529; 530 Д
innodb_buffer_pool_awe memmb, 530 Двойная лицензия, 15
innodb_buffer_pool_size, 236; 527; 529; 530
innodb_data_file_path, 215; 236; 500; 525-528;
ж
Журнал
531; 535; 546; 572 бинарный, 345; 348
innodb_data_home_dir, 236; 525-528; 531; запросов, 345
535;546;572 медленных запросов, 345; 351
innodbfastshutdown, 236; 531 обновлений, 226; 345; 347
innodb_file_per_table, 531; 544 ошибок, 100; 101; 103; 148; 345; 346; 597
innodbfiletothreads, 531 таблиц ISAM, 345
innodb_flush_log_at_trx_cornrnit, 236; 527;
529; 531; 561 К
innodb_flush_method, 236; 529; 532; 561 Ключ
innodb_force_recovery, 236; 532; 549 внешний, 29; 37; 38; 43; 65; 66; 68; 100; 539;
innodb_lock_wait_timeout, 236; 529; 532; 559 541; 542; 562
innodb_log_arch_dir, 236; 529; 532; 533 Код ошибки
innodblogarchive, 236; 532 1005 (ER_CANT_CREATE_TABLE), 574
innodb_log_buffer_size, 236; 527; 529; 532 1016 (ER_CANT_OPEN_FILE), 574
innodbjog_file_size, 236; 527; 529; 533 1114 (ER_RECORD_FILE_FULL), 574
1205 (ER_LOCK_WAIT_TIMEOUT), 574
innodblogfilesingroup, 236; 529; 533
1213 (ER_LOCK_DEADLOCK), 574
innodb_log_group_home_dir, 236; 529; 532;
1216 (ER_NO_REFERENCED_ROW), 574
533 1217 (ER_ROW_IS_REFERENCED), 574
innodb_max_dirty_pages_pct, 533 Компания MySQL AB
innodbmirroredloggroups, 236; 533 http://www.mysql.com, 15
innodbopenfiles, 533 коммерческая лицензия, 29; 30
innodbthreadconcurrency, 236; 529; 533; 567 поддержка, 21; 24; 28; 31; 40
s сертификация, 28
Компилятор
SMP, См. Симметричная аСС,87;88; 188
многопроцессорная система, 78; 170; 172; СС,88
175; 177 сс/схх, 89
сс-5.0, 86
ссс, 85; 177
-temp-pool, 161; 230 есс, 85
egcs,89; 118; 122; 178; 179; 183; 189; 190
Предметный указатель 615

gcc, 85-90; 118; 122; 123; 127-131; 173; MERGE, 25; 42; 72; 75; 105; 361; 381; 498;
176-190; 192-196; 199; 200;451 509; 510-512; 521; 549
pgcc,82; 122; 451; 452 MylSAM, 20; 22-25; 37; 38; 40; 42; 45; 46;
xlC_r,87; 188 59; 62; 64; 65; 68; 72; 153; 159; 160; 161;
Конструкция 163-165; 168; 213; 215; 218; 223-227;
CHANGE имястолбца, 59 229; 230; 239-241; 243; 247; 248; 250;
DELAYED, 46; 59; 63; 71; 164; 172; 224; 252; 318-322; 324; 326; 329; 330; 333-
241; 246; 262; 425; 429; 434; 489; 578 338; 345; 366; 374; 375; 381; 383; 394;
DROP INDEX, 59; 165; 559; 585 396; 403; 404; 411; 416; 417; 425^31;
DROP имястолбца, 59 434; 436; 437; 440; 441; 446; 447; 453-
IF EXISTS, 17; 25; 59 455; 457; 458; 460; 461; 463; 465; 485;
IGNORE, 44; 58; 59; 68; 72; 162; 232; 233; 489; 491; 492; 498-505; 507-512; 517-
411; 444; 445; 468; 549; 574; 586 519; 521; 523; 530; 537; 543-545; 550;
LIMIT, 39; 46; 47; 59; 158; 380; 418; 420; 577-579; 598; 607
423; 424; 434; 440; 476; 477; 586 Монитор InnoDB, 563; 579
LOW_PRIORITY, 59; 161; 227; 429; 434
ORDER BY, 21; 46; 59; 72-74; 162; 165; H
166; 250; 251; 263; 327; 340; 412; 417- Недействительный результат чтения, 63
419; 421-423; 427; 439; 440; 451; 610
SQL_SMALL_RESULT, 59; 417 о
WHERE, 20; 21; 58; 61; 64; 66; 70; 74; 75; Оболочка
151; 152; 157; 247; 267; 269; 307; 309; bash, 112; 185; 186; 203; 210; 389
347; 348; 362; 409-413; 416-422; 424; Bourne, 17; 210
427; 428; 432; 437-440; 476; 491; 512; sh, 16; 126; 145; 146; 185; 186; 191; 203; 210;
537; 554; 555; 557; 558; 586; 592; 593; 601
599; 606 tcsh, 17; 112; 203; 210; 601
Контрольная сумма MD5, 61; 90; 91; 93; 266; zsh,210
301; 427 Оператор
Курсор, 42 ALTER TABLE, 24; 45; 46; 59; 71; 75; 105;
156; 159; 163-165; 246; 248; 279; 324;
л 331; 361; 414; 426; 427; 457; 458; 489;
Лицензия GNU General Public License, 15; 499; 501; 504; 510-512; 521; 537; 539-
18; 32; 582 541; 543; 545; 549; 559; 573; 578; 581;
598;607-610
M ANALYZE TABLE, 59; 71; 72; 321; 324;
Механизм хранения 381; 408; 411; 415; 416; 424; 485; 512;
BDB, 23; 62; 71; 98; 126; 147-149; 155; 214; 519; 522;587
215; 223; 228; 238; 239; 242; 252; 350; CHECK TABLE, 55; 59; 113; 164; 165; 229;
396; 411; 430; 432-434; 498; 499; 515- 321; 322; 330; 333; 485; 507; 508; 522;
521 548; 580; 585; 595
HEAP, 40; 70; 73; 246; 382; 417; 422; 429; CREATE DATABASE, 59; 389; 390; 490; 585
430; 437; 438; 453; 491; 498; 513 CREATE TABLE, 24; 25; 40; 45; 53; 59; 61;
InnoDB, 23; 24; 29; 37; 38; 43; 62; 64; 65; 68; 65; 71; 105; 155; 156; 230; 233; 240; 246;
72; 97; 98; 100; 103; 120; 126; 147; 156; 247; 279; 280; 331; 381; 425; 437; 458;
161; 214; 215; 223; 229; 238; 242; 243; 487; 488; 490; 491; 495; 498-500; 502;
252; 318; 319; 350; 361; 375; 380; 381; 509; 513; 514; 518; 535; 536; 539-542;
396; 430; 432; 433; 434; 437; 451; 490; 558; 559; 563; 578; 580; 581
498;500; 518; 523-564; 567-574; 577- AVG_ROW_LENGTH, 24; 96; 331; 598
581;598 MAX_ROWS, 24; 96; 246; 247; 331; 514;
MEMORY, 42; 246; 358; 382; 430; 437; 438; 598
440; 469; 479; 481; 486; 490; 494; 496; DROP DATABASE, 59; 105; 162; 164; 267;
498; 499; 513-515; 567; 576 361; 389; 390; 559; 569; 580
EXPLAIN, 21; 52; 53; 59; 408; 409; 411; 413-
416; 418-420; 422-424; 427; 560; 585
616 Предметный указатель

EXPLAIN SELECT, 52; 53; 59; 408; 413; Mac OS, 77; 81; 88; 109-111; 114; 117; 138;
423; 560 144; 179; 214; 218; 245;516
FLUSH, 53; 59; 71; 75; 105; 151; 152; 229; NetBSD,77;185
246; 252; 262; 269; 271; 277; 289; 294; Novell NetWare, 77; 112
304; 306-309; 318; 320; 322; 345-348; OpenBSD, 77; 185
352; 364; 371; 374; 375; 379; 381; 393- OS/2 Warp, 77; 196
395; 425; 426; 447; 454; 455; 492; 493; SCO OpenServer, 77; 194; 516
508; 510; 512; 519; 592; 593; 606 SCO UnixWare, 78; 196; 516
GRANT, 139; 140; 152; 160; 165; 221; 228; SGI Irix, 78; 89; 193
266; 270; 271; 273; 277-280; 282; 283; Solaris, 24; 77; 78; 86; 127; 130-132; 179-
286; 288; 289; 292; 296; 298-300; 302- 183; 214; 218; 224; 227; 252; 448; 452;
310; 317; 374; 381; 407 454; 457; 516; 594
LOAD DATA INFILE, 44; 47; 59; 72; 105; SunOS, 78; 89; 131; 190
106; 224; 231; 239; 244; 248; 253; 273; Tru64Unix,78
279; 294; 319; 320; 373; 384; 391; 425; UNIX, 16; 21; 22; 38; 77; 141; 144; 194; 358;
426; 429; 461; 468; 481-483; 489; 493; 359; 361; 384; 461; 611; 613
494; 514; 609; 610 Windows, 15; 16; 21; 22; 38; 49; 51; 52; 55;
LOCK TABLES, 63; 64; 243; 278; 280; 318; 56; 78; 91; 93;95-99; 101-107; 133-138;
426; 432-434; 448; 491; 492; 508; 519; 144; 148-154; 156; 159; 167; 168; 197;
532;558-560; 579 198; 203; 206; 208-210; 213; 214;224;
OPTIMIZE TABLE, 59; 71; 72; 164; 321; 225; 229; 230; 241; 245; 248; 251; 253;
324; 333; 334; 381; 427; 429; 485; 505; 272; 281; 282; 290; 293; 302; 311; 318;
506; 512; 519; 522; 609 327; 346; 347; 352-355; 357; 359; 374;
RENAME DATABASE, 43 423; 431; 457; 459; 473; 483; 490; 512;
RENAME TABLE', 42; 59; 512; 542; 545; 559 524; 525; 527; 528; 530; 531; 534; 550;
REPAIR TABLE, 55; 59; 71; 72; 113; 157; 561; 563; 572; 576; 577; 579; 583; 590;
162; 163; 229; 241; 242; 248; 319; 321; 591; 598; 600; 603-605; 609; 613
324; 330; 333; 381; 457; 485; 507; 508; Опция
512; 522; 609 -analyze, 327; 333; 411; 416; 485; 502
REPLACE, 21; 44; 59; 70; 72; 227; 320; 404; ~ansi,57;223;238
512; 558; 565;566; 587 AVG_ROW_LENGTH, 24; 96; 331; 598
RESET, 17; 59; 349; 364; 385; 398; 399 -backup, 325; 462
SHOW INDEX, 162; 411; 416 -basedir, 216; 224; 354
SHOW MASTER STATUS, 161; 280; 375; -big-tables, 224; 453; 598
376; 379; 393; 395; 399; 401 —bind-address, 224
SHOW OPEN TABLES, 162 bulk_insert_buffer_size, 161; 235; 239; 257;
SHOW SLAVE STATUS, 162; 280; 369; 372; 425; 503
391; 394; 399; 401 -character-sets-dir, 224; 325; 341; 345; 468;
UNLOCK TABLES, 63; 320; 375; 393; 395; 479; 485; 496
426; 432; 448; 559; 560 -character-sets-dir, 224; 325; 468; 479; 485; 496
Операционная система -check, 93; 325; 485; 486; 493
AIX, 77; 86;87;90;188-190; 214; 516 —check-only-changed, 325; 486
Amiga, 77 -chroot, 224
BSDI,77;90; 185; 186 -config-file, 220
FreeBSD, 77; 88; 89; 130; 131; 145; 183; 184; -console, 100; 101; 224; 346; 527; 534; 563;
248; 516 579
HP-UX, 77; 87; 187; 188; 214 -core-file, 176; 216; 224
Linux, 24; 77; 78; 81; 85; 86; 89; 91; 92; 94; —core-file-size, 216
107; 109; 122; 127; 131; 133; 135; 138; —correct-checksum, 325
145; 161; 170-174; 176-178; 184; 197; -datadir,216;224;353;358
199; 213; 214; 216; 218; 225; 228; 230; -data-file-length, 325
268; 290; 293; 351; 360; 405; 448; 451; -debug, 101; 136; 149; 224; 295; 323; 462;
452; 456; 457; 483; 516; 528; 529; 532; 468; 479; 486; 489; 493; 494; 496
561; 575; 591; 594; 597
Предметный указатель 617

-default-character-set, 224; 340; 380; 468; -master-host, 384; 386


486; 489; 496 -master-info-file, 386
-default-collation, 224; 340 —master-password, 384; 386
-defaults-extra-file, 207; 209; 216 -master-port, 384; 386
-defaults-file, 209; 216; 359 -master-ssl, 384; 386; 387
-default-storage-engine, 224 -master-ssl-ca, 384; 386
-default-table-type, 224; 252 -master-ssl-capath, 384; 386
-delay-key-write, 224; 225; 229; 395; 502; —master-ssl-cert, 384; 386
503; 606 -master-ssl-cipher, 384; 386
-delay-key-write-for-all-tables, 225 -master-ssl-key, 384; 387
-description, 327; 416 -master-user, 384; 387
-des-key-file, 225 MAX_ROWS, 24; 96; 246; 247; 331; 514; 598
-enable-locking, 161; 225 -max-relay-log-size, 387; 388
-enable-named-pipe, 225; 590 -medium-check, 325; 486
-err-log, 216 -memlock, 227; 244
-example, 220 -myisam-recover, 227; 241; 248; 334; 430;
-exit-info, 225 502; 503
-extend-check, 323; 325 —mysqladmin, 220
-external-locking, 132; 161; 225; 241; 503 -mysqld,217;220
-fast, 322; 325; 334; 486; 502 -mysqld-version, 217
-flush, 225; 241; 489; 493; 606 -new, 155; 157; 208; 228
-force, 171; 322; 325; 326; 462; 468; 479; -nice, 217
481; 486; 489; 494; 607 -no-defaults, 209; 217; 291
-help, 16; 22; 101; 119; 121; 136; 140; 141; -no-log, 220
147; 168; 203; 204; 207; 212; 220; 223; —no-symlinks, 326
277; 321-323; 406; 450; 451; 461; 462; -old-passwords, 159; 298-300
468; 479; 481; 483; 485; 487; 488; 493; -old-protocol, 166; 228; 599
494; 496 -one-thread, 228
-information, 325 -open-files-limit, 184; 185; 217; 228; 446;
-init-file, 225; 243; 514; 515 533;601
-keys-used, 326; 425; 426 -pager, 469; 472
-language, 225; 341 -parallel-recover, 326
--ledir, 217 -password, 220; 281; 295; 310
-log, 72; 74; 141; 161; 216; 217; 220; 224; -pid-file, 217; 221; 228; 249; 353
226; 227; 239; 245; 319; 346-349; 351- -port, 149; 209; 217; 228; 249; 290; 352; 354;
353; 376; 377; 382; 386; 398; 399; 401; 355; 358; 359; 469; 479; 481; 484; 486;
595; 597; 607 490; 493; 494; 496; 590
-log-bin, 72; 226; 239; 319; 346; 348; 349; -print-defaults, 154; 209
352; 353; 376; 398; 399; 401 query_cache_type, 161; 237; 249; 259; 264;
-log-bin-index, 226; 349 362;363;562
-log-error, 161; 216; 217; 224; 226; 346; 353 -quick, 169; 207; 326; 328; 329; 467; 469;
-log-isam, 226; 353 486; 487; 490; 594
—log-long-format, 226; 351 read_buffer_size, 161; 237; 250; 259; 323;
-log-queries-not-using-indexes, 226 449; 450; 451; 529; 530
-log-short-format, 226 read_rnd_buffer_size, 161; 237; 250; 259;
-log-slave-updates, 382; 386; 398; 401 422; 423; 449; 451; 453
-log-slow-queries, 226; 245; 351; 352 -read-only, 325; 387
-log-update, 226; 347; 352; 353 -recover, 323; 324; 326; 328; 508
log-warnings, 161; 227 -relay-log, 371; 387; 391
-log-warnings, 227; 377; 386; 597 -relay-log-index, 387
-low-priority-updates, 227; 395; 434 -relay-log-info-file, 387
-master-connect-retry, 367; 370; 383; 384; —relay-log-purge, 387
386;391 —relay-log-space-limit, 387
618 Предметный указатель

-replicate-do-db, 388; 392 -sql-mode, 57; 58; 158; 162; 223; 230; 232; 238
--replicate-do-table, 388; 392; 393 -symbolic-links, 229
-replicate-ignore-db, 388; 389; 392 ~tcp-ip, 220
--replicate-ignore-table, 389; 392 -temp-pool, 161; 230
--replicate-rewrite-db, 390 —timezone, 217
-replicate-wild-do-table, 388; 389; 392; 393 "tmpdir, 230; 327; 328; 353; 493; 598; 609
-replicate-wild-ignore-table, 389; 390; 392 -transaction-isolation, 58; 158; 230; 552
-report-host, 390 -unpack, 327; 467
-report-port, 390 -update-state, 322; 325; 331; 502; 508
-safe-mode, 228 -user, 106; 115-117; 119-121; 139-141; 144;
-safe-recover, 323; 326; 328; 332 146; 171; 182; 185; 203; 217; 220; 221;
-safe-show-database, 160; 228; 271 224; 231; 269; 281; 302-305; 468; 470;
-safe-user-create, 228; 271 480; 481; 484; 487; 491; 493; 495; 496;
-secure-auth, 228; 250; 271 601; 603
-set-auto-increment, 327 -verbose, 147; 205; 223; 323; 327; 330; 416;
-set-character-set, 124; 153; 326; 340 449; 451; 463; 470; 478; 480; 487; 491;
-silent, 136; 322; 323; 329; 333; 334; 463; 495; 496
470; 480; 486; 495; 607 -version, 205; 220; 231; 323; 463; 470; 480;
-skip-bdb, 215; 228; 238; 242; 395; 516; 517 481; 484; 487; 491; 495; 497
—skip-concurrent-insert, 229 -wait, 323; 463; 470; 480
—skip-delay-key-write, 229 -with-berkleydb, 82
-skip-external-locking, 113; 161; 227; 229; -with-debug, 82; 90; 124; 131; 189; 224; 230;
323; 325; 328; 329; 448; 462; 463; 503; 452; 479; 607
606;607 -with-innodb, 82; 85-89; 194; 214
-skip-grant-tables, 140; 229; 271; 291; 295; -with-libwrap, 82; 194
604; 605 -with-names-z-libs, 82
-skip-host-cache, 229; 293; 455 —without-innodb, 161
-skip-innodb, 161; 215; 229; 242; 395 -with-raid, 82
—skip-isam, 229; 242
-skip-locking, 161; 229 П
-skip-name-resolve, 104; 184; 229; 271; 293; Пакет RPM, 90; 107; 108; 109; 145; 203; 213;
455 218; 219
—skip-networking, 229; 271; 455 Переменная
-skip-new, 229; 240 серверная
-skip-safemalloc, 230; 452 autocommit, 257
-skip-show-database, 230; 271; 280 backjog, 182; 235; 238; 449
-skip-slave-start, 377; 390 basedir, 98; 134; 146; 147; 235; 238; 354;
-skip-stack-trace, 230 356;357
-skip-symbolic-links, 229; 458 bdb_cache_size, 235; 238; 449
-skip-thread-priority, 186; 230 bdbjiome, 235; 238
—slave_compressed_protocol, 390 bdb_log_buffer_size, 235; 238
-slave-load-tmpdir, 319; 373; 391 bdbjogdir, 235; 238
bdb_max_lock, 235; 238; 239; 517
—slave-net-timeout, 391
bdb_shared_data, 235; 239
-slave-skip-errors, 383; 391
bdbjmpdir, 235; 239
-socket, 104; 209; 217; 230; 352; 354; 358; bdb_version, 235; 239
359; 470; 480; 481; 484; 487; 491; 493; bigjables, 257; 259
495; 496; 590; 591; 610; 611 binlog_cache_size, 235; 239; 245; 257; 262;
sort_buffer_size, 161; 234; 237; 251; 254; 350; 351; 449; 517; 529
259; 264; 323; 324; 332; 334; 422; 423; bulk_insert_buffer_size, 161; 235; 239; 257;
450; 451; 529 425; 503
-sort-index, 327; 333; 334; 416; 467 character_set, 235; 239; 240; 257
-sort-records, 327; 333; 416 character_sets, 235; 240
-sort-recover, 324; 326; 328 concurrent_insert, 235; 240; 257
Предметный указатель 619

connecttimeout, 209; 235; 240; 257; 449; key_buffer_size, 72; 166; 208; 231; 234;
470;480; 484; 597 236; 243; 244; 255-258; 263; 323-326;
convert_character_set, 235; 257 332; 416; 426; 441; 443; 445; 449-451;
datadir, 97; 98; 134; 140; 146; 147; 207; 218; 453; 530
222; 235; 238; 240; 355; 358; 517 key__cache__age_threshold, 236; 244; 255;
default_week_format, 235; 240; 257 444
delay_key_write, 235; 240; 257 key_cache_block_size, 236; 244; 255; 256;
delayed_insert_limit, 235; 241; 257; 449 445
delayed_insert_timeout, 235; 241; 257; 449 key_cache_division_limit, 236; 244; 255;
delayed_queue_size, 235; 241; 257; 449 444
flush, 71; 140; 229; 235; 241; 257; 271; 277; language, 222; 236; 244
279; 289; 293-295; 304; 328; 329; 345; large_files_support, 236
347; 348; 350; 352; 425; 447; 449; 454; locaUnfiie, 236; 244; 258
455; 467; 478; 479; 510; 567; 593; 605 locked_in_memory, 236; 244
flushjime, 235; 241; 257; 449 log, 47; 71; 74; 100; 120; 129; 141; 148; 155;
ft_boolean_syntax, 235; 241; 258 161; 182; 226; 227; 236; 238; 244-247;
ft_max_word_len, 235; 241; 323; 324 258; 259; 293; 319; 346; 347; 351; 352;
ft_min_word_len, 235; 242; 323; 324 368; 370-373; 375-377; 386-388; 398;
ft_query_expansion_limit, 235; 242 415; 425; 473; 493; 513; 520; 521; 527;
ft_stopword_fiie, 235; 242; 324 534-536; 548; 564-567; 589
have_bdb,215;235;242 log_bin, 236; 244; 259
have_innodb,215;235;242 log_slave_updates, 236; 244
have_isam,215;236;242 log_slow_queries, 236; 245
have_openssl, 215; 236; 242; 313 log_update, 236; 245; 259
have_query_cache, 215; 236; 362; 364 log_warnings, 236; 258
have_raid,215;236;242 long_query_time, 45; 226; 236; 245; 258;
have_symlink, 215; 236; 457 264; 345;351;449; 479
init_file, 236; 243 low_priority_updates, 236; 245; 258; 259
innodb_additional_mem_pool_size, 236; lower_case_table_names, 55; 236; 245; 449;
527; 529; 530 541;550
innodb_buffer_pool_size, 236; 527; 529; 530 max_allowed_packet, 208; 210; 211; 236;
innodb_data_file_path, 215; 236; 500; 525- 245; 248; 258; 449; 453; 470; 484; 491;
528;531;535;546; 572 492;595;596;597
innodb_data_home_dir, 236; 525-528; 531; max_binlog_cache_size, 236; 245; 258; 351;
535; 546;572 449; 517
innodb_fast_shutdown, 236; 531 max_binlog_size, 236; 246; 258; 348; 372
mnodb_file_io_threads, 236 max_connect_errors, 236; 246; 258; 449;
innodb_flush_log_at_trx_commit, 236; 527; 593;594
529;531; 561 max_connections, 174; 228; 236; 246; 258;
innodb_flush_method, 236; 529; 532; 561 274; 307; 446; 449; 529; 530; 594; 601
innodb_force_recovery, 236; 532; 549 max_delayed_threads, 236; 246; 258; 449
innodbjock_wait_timeout, 236; 529; 532; maxerrorcount, 237; 246; 258
559 max_heap_table_size, 237; 246; 258; 449
innodb_log_arch_dir, 236; 529; 532; 533 maxjoin_size, 237; 246; 247; 258; 259; 413;
innodb_log_archive, 236; 532 449; 470; 477; 484
innodb_log_buffer_size, 236; 527; 529; 532 max_relay_log_size, 237; 246; 247; 258;
innodb_log_file_size, 236; 527; 529; 533 372;387
innodb_log_files_in_group, 236; 529; 533 max_sort_length, 73; 237; 247; 258; 449
innodb_log_group_home_dir, 236; 529; 532; maxjmpjables, 237; 247; 258; 446; 449
533 max_user_connections, 237; 247; 258; 270;
innodb_mirrored_log_groups, 236; 533 307
innodb_thread_concurrency, 236; 529; 533; max_write_lock_count, 237; 247; 258; 434;
567 449
interactive_timeout, 236; 243; 253; 258; 449; myisam_max_extra_sort_file_size, 161; 237;
597 248; 258; 503
join_buffer_size, 236; 243; 449 myisam_max_sort_file_size, 237; 248; 258;
503
620 Предметный указатель

myisam_recover_options, 237; 248 состояния


myisam_repair_threads, 237; 248; 258 Aborted_clients, 260; 261; 597
myisam_sort_buffer_size, 237; 248; 258; Abortedconnects, 260; 261
449; 503 Bytes_received, 260; 262
net_buffer_length, 237; 245; 248; 258; 449; Bytes_sent, 260; 262
451; 453; 470; 484; 492 Connections, 252; 260; 262; 265; 426
net_read_timeout, 237; 248; 258; 449 Created_tmp_disk_tables, 260; 262
net_retry_count, 237; 248; 258; 449 Createdjmp_files, 260; 262
net_write_timeout, 237; 249; 258; 449 Created_tmp_tables, 260; 262
openjilesjimit, 237; 249; 481; 601 Delayed_errors, 260; 262
pid_file, 237; 249 Delayedinsertthreads, 260; 262
port, 100; 126; 141; 143; 146; 149; 208; 222; Delayedwrites, 260; 262
237; 249; 268; 318; 354-359; 385; 592 Flushcommands, 260; 262
protocol_version, 237; 249 Handler_delete, 260; 262
query_cache_limit, 237; 249; 259; 363 Handler_read_first, 260; 262
query_cache_size, 231; 235; 237; 249; 259; Handler_read_key, 260; 262
360; 362; 562 Handler_read_next, 260; 263
query_cache_type, 161; 237; 249; 259; 264; Handler_read_prev, 260; 263
362;363; 562 Handlerreadrnd, 260; 263
read_buffer_size, 161; 237; 250; 259; 323; Handler_read__rnd_next, 260; 263
449-451; 529; 530 Handlerupdate, 260; 263
read_md_buffer_size, 161; 237; 250; 259; Handlerwrite, 260; 263
422; 423; 449; 451; 453 Key_blocks_used, 244; 260; 263
rpl_recovery_rank, 237; 259 Key_read_requests, 243; 260; 263
serverjd, 237; 251; 259; 376; 377 Key_reads,243;261;263
skip_external_locking, 237; 251 Key_write_requests, 243; 261; 263
skip_networking, 237; 251 Key_writes,243;261;263
skip_show_database, 237; 250; 251 Max_used_connections, 261; 263
slavejiettimeout, 237; 248; 251; 259; 383 Not_flushed_delayed_rows, 261; 263
slowjaunchjime, 237; 251; 259; 264; 449 Not_flushed_key_blocks, 261; 263
socket, 100; 122; 126; 141; 143; 146; 149; Open_files,261;263
186; 208; 222; 237; 251; 290; 354-359; Open_streams, 261; 263
590; 591; 610; 611 Open_tables,261;263
sort_buffer_size, 161; 234; 237; 251; 254; Openedjables, 252; 261; 263; 447
259; 264; 323; 324; 332; 334;422; 423; Qcachejree_blocks, 261; 263; 363; 364
450;451;529 Qcachejfree_memory, 261; 264; 364
sql_mode, 57; 58; 158; 232; 237; 252; 379; Qcachejiits, 261; 264; 361; 364
380; 381 Qcachejnserts, 261; 264; 364
table_cache, 228; 237; 252; 259; 263; 446; Qcache_lowmem_prunes, 261; 264; 363; 364
447; 449; 450; 451; 601 Qcache_not_cached, 261; 264; 364
tablejype, 237; 252; 259; 380; 499 Qcache_queries_in_cache, 261; 264; 364
thread_cache_size, 237; 252; 259; 265; 427 Qcachejotal_blocks, 261; 264; 363; 364
thread_stack, 176; 237; 252; 449; 453 Questions, 141; 261; 264; 446; 478; 479
timezone, 237; 252; 611 Select_fulljoin,261;264
tmp_table_size, 237; 252; 259; 262; 449; Select_full_rangejoin, 261; 264
453; 514; 598 Select_range, 261; 264
tmpdir, 230; 237; 239; 252; 253; 319; 327; Select_range_check, 261; 264
353; 373; 391; 423; 517; 599 Select_scan, 261; 264
tx_isolation, 237; 253; 260; 552 Slave_open_temp_tables, 261; 264
version, 52; 54; 103; 132; 141; 182; 195; Slave_running, 261; 264
216; 217; 237; 253; 272; 291;335;337; Slowjaunchjhreads, 261; 264
369; 463; 465; 478; 520; 536; 580; 590; Slow_queries, 245; 261; 264
591; 595; 606; 611 Sort_merge_passes, 261; 264
waitjimeout, 184; 237; 243; 253; 260; 449; Sort_range, 261; 264
595;597 Sort_rows,261;265
warning_count, 260 Sort_scan, 261
Table_locks_immediate, 261; 265; 431
Предметный указатель 621

Table_locks_waited, 261; 265; 431 mysqlc, 104


Threads_cached, 261; 265 mysqlcc, 127; 202; 206; 460; 483
Threads_connected, 261; 265 mysqlcheck, 22; 202; 206; 321; 460; 485
Threads_created, 252; 261; 265 mysqld, 38; 43; 46; 47; 53; 54; 55;^57; 71; 74;
Threads_running, 261; 265 82; 85; 86; 89; 93; 94; 96; 98-104; Г06;
Uptime, 141; 261; 265; 446; 478 109-111; 113-123; 129-132; 134; 135;
Подзапрос, 39; 61; 66; 410 140; 141; 143-149; 153-155; 158; 160-
Полнотекстовый поиск, 23 167; 170-178; 180-186; 190-193; 195;
Потоки MIT-pthreads, 47; 73; 127; 131; 132; 149; 197; 202; 206-208; 212- 232; 234; 238-
179; 183; 184; 190; 271; 292; 448; 452; 591 240; 242-244; 246; 249; 251-253; 256;
Представление, 37; 43; 66 262; 269-272; 277; 289; 291-293; 295;
Привилегия 312; 316; 319; 322-325; 328; 329; 331;
CREATE TEMPORARY TABLES, 160 334; 341; 345-352; 354-360; 362; 376;
EXECUTE, 160; 278 385; 390; 424; 434; 446; 447; 449-455;
FILE, 160 458; 459; 462; 463; 467; 479; 483; 485;
LOCK TABLES, 160 491; 502; 503; 507; 508; 516; 517; 519;
REPLICATION CLIENT, 160; 278; 280 520; 524-528; 530; 534; 535; 537; 544;
REPLICATION SLAVE, 160; 278; 280; 374; 545; 547-550; 552; 562; 563; 572; 579;
387 589-601; 603-611; 613
SHOW DATABASES, 160; 177; 228; 230; --ansi, 57; 223; 238
250; 251; 271; 278; 280 -sql-mode, 57; 58; 158; 162; 223; 230; 232;
SUPER, 160; 234; 250; 253; 255; 270; 278- 238
280; 350; 373; 374; 387; 533; 552; 594 mysqldhow, 107
Программа mysqld-max, 82; 96; 98; 99; 212; 213; 216;
mysql, 15-18; 21; 25; 26; 28-34; 36; 37; 39; 217; 225; 354; 355; 459; 527
41-46; 48; 50; 51; 53-56; 58; 60; 61; 64; mysqld-max-nt, 98; 99; 225; 355; 459
67; 68; 71; 72; 74; 80; 81; 83-123; 125- mysqld-nt, 98; 99; 106; 225; 355-357; 604
127; 131-146; 148-155; 157-160; 163; mysqld-opt, 98; 99
165-169; 171-173; 175; 177; 178; 179- mysqldump, 53; 54; 65; 66; 107; 153; 155-
189; 191-203; 205-211; 213-215; 217- 157; 160; 164; 168; 169; 202; 203; 206;
219; 221-223; 228; 230; 232; 234-237; 208; 232; 295; 319; 376; 377; 393; 458;
243; 253; 254; 256; 257; 260; 266-273; 461; 487; 488; 490-492; 520; 542; 546;
277-283; 286; 290-300; 302-310; 312; 547; 551; 562; 573; 584
313; 317; 320; 332; 340; 341; 345-347; mysqlhotcopy, 202; 206; 209; 319; 461; 487;
350-352; 354-358; 360-364; 368; 374; 492; 493
375; 377; 379; 381; 386; 393; 395; 400; mysqlimport, 169; 202; 206; 272; 461; 493-
401; 404; 406; 407; 414; 415; 420; 431; 495;584
432; 439; 442-445; 447; 449; 450; 459- mysqlshow, 103; 137; 141; 202; 203; 206;
461; 467-469; 471-477; 482; 483; 487; 461; 495; 496; 599
492; 495; 509; 510; 513; 521; 524; 527; WinMySQLAdmin, 96; 98; 167
528; 534-537; 541; 542; 547; 563; 564; Протокол
577; 579; 584; 589; 59(Г-594; 596; 597; клиент-серверный, 43; 242; 249
599; 601-607; 610-612
mysqladmin, 16; 46; 52-54; 74; 96; 101-103; p
105-107; 110; 112; 113; 132; 139-141; Режим
145; 148; 151; 152; 167; 169; 186; 190; ANSI, 18; 47; 56-58; 61; 87; 118; 188; 232;
193; 202; 203; 206; 220; 222; 229; 270; 233; 420; 490
271; 277; 279; 287; 289; 291-293; 295; ANSI_QUOTES, 58; 232; 233; 490
304; 308-310; 328; 329; 331; 345; 347; DB2, 233; 404; 406; 582
348; 350; 352; 355; 358; 371; 375; 382; IGNORE_SPACE, 58; 232; 233; 468
425; 446; 447; 450; 454; 455; 460; 467; MAXDB, 233
477-479; 510; 534; 589-593; 595; 603; MSSQL, 233
605-609; 611 MYSQL323, 233
MYSQL40, 233
622 Предметный указатель

NO_AUTO_VALUE_ON_ZERO, 232
NO_DIR_IN_CREATE, 233; 381
Семафор, 46; 47; 78; 104; 172; 370; 371; 455;
NO_FIELD_OPTIONS, 233
516; 533; 567
NO_KEY_OPTIONS, 233
Сервер баз данных, 18
NO_TABLE_OPTIONS, 233
NO_UNSIGNED_SUBTRACTION, 233 встроенный, 39; 223
ONLY_FULL_GROUP_BY, 58; 233 Симметричная многопроцессорная
ORACLE, 233 система, 78; 170
PIPES_AS_CONCAT, 58; 233 Система управления базами данных, 18
POSTGRESQL, 233 Список рассылки MySQL, 48
REAL_AS_FLOAT, 58; 233 anounce, 48
Репликация, 23; 40; 71; 365; 366; 380; 395; benchmarks, 49; 175; 404; 406
396; 543;584 benchmarks-digest, 49
--log-slave-updates, 382; 386; 398; 401 bugs, 48; 50; 51; 53; 54; 84; 126; 213; 401
--log-warnings, 227; 377; 386; 597 bugs-digest, 48
—master-connect-retry, 367; 370; 383; 384; gui-tools, 49
386;391 gui-tools-digest, 49
-master-host, 384; 386 internals, 48; 90; 127; 172; 343
—master-info-file, 386 internals-digest, 48
-master-password, 384; 386 Java, 49
-master-port, 384; 386 java-digest, 49
-master-ssl, 384; 386; 387 msql-mysql-modules, 50
—master-ssl-ca, 384; 386 msql-mysql-modules-digest, 50
-master-ssl-capath, 384; 386 myodbc, 49
—master-ssl-cert, 384; 386 myodbc-digest, 49
-master-ssl-cipher, 384; 386 mysql, 48
-master-ssl-key, 384; 387 mysql-digest, 48
-master-user, 384; 387 mysqldoc, 49; 127
—max-relay-log-size, 387; 388 mysqldoc-digest, 49
-read-only, 325; 387 packagers, 49
-relay-log, 371; 387; 391 packagers-digest, 49
-relay-log-index, 387 plusplus, 49; 50
—relay-log-info-file, 387 plusplus-digest, 50
-relay-log-purge, 387 Win32, 49; 133
-relay-log-space-limit, 387 win32-digest, 49
-replicate-do-db, 388; 392 Стандарт
~replicate-do-table, 388; 392; 393 SQL
-replicate-ignore-db, 388; 389; 392 1999, 18;56
-replicate-ignore-table, 389; 392 2003, 18; 42; 56
—replicate-rewrite-db, 390 SQL-92, 18; 56
-replicate-wild-do-table, 388; 389; 392; 393 СУБД, См. Система управления базами
-replicate-wild-ignore-table, 389; 390; 392 данных, 18; 19; 28; 29; 31; 33; 35; 36; 39;
-report-host, 390 47; 49; 56; 60; 62; 63; 67; 68; 79; 81; 150;
-report-port, 390 231; 403; 404; 407
-skip-slave-start, 377; 390 Сценарий
—slave_compressed_protocol, 390 bin/mysqlbug, 85
-slave-load-tmpdir, 319; 373; 391 Build-tools/Do-compile, 85
—slave-net-timeout, 391 configure, 46; 54; 85-90; 118; 119; 121-124;
-slave-skip-errors, 383; 391 126-131; 161; 164; 173; 176-196; 312;
Репозиторий BitKeeper, 39; 41; 42; 79; 80; 82; 340; 342; 343; 358; 360; 386; 452; 516;
83; 124; 125; 127; 133; 135; 136 528; 600; 607; 611; 612
Предметный указатель 623

mysql.server, 116; 120; 144-146; 173; 181; Утилита


202; 206; 213; 218; 219; 223; 270; 346; gunzip, 114-119; 169; 198
611 myisamchk, 22; 24; 55; 113; 124; 153; 157;
mysql_fix_privilege_tables, 154; 158; 159; 163; 165; 203; 206; 213; 229; 319-340;
165; 168; 213; 290; 297; 298 345; 411; 416; 425; 426; 430; 448; 458;
mysql_install_db, 94; ПО; 115; 116; 118; 120; 463; 465; 467; 485; 493; 500-502; SOS-
138; 139; 140; 142-144; 149; 171; 184; SOS; 522;598; 607
191; 202; 213; 290; 304; 358; 577 myisampack, 24; 45; 203; 206; 327; 339; 425;
mysql_multi, 202; 213; 219; 220-222; 359 460-464; 466; 467; 500; 504; 506; 509;
mysqlaccess, 54; 117; 277; 289; 295; 460 510; 522
mysqld_safe, 47; 74; 110; 111; 114; 115; 117; mysqlaccess, 54; 117; 277; 289; 295; 460
119; 121; 140; 141; 144-147; 153; 160; mysqlbinlog, 72; 106; 203; 206; 320; 350;
161; 174-176; 184; 185; 190; 191; 195; 371; 401; 460;480-483;547
202; 206; 213; 215-218; 220-224; 228; mysqlhotcopy, 202; 206; 209; 319; 461; 487;
252; 270; 334; 346; 354; 358; 359; 450; 492; 493
451; 534; 579; 593; 596; 601; 604; 605; perror, 203; 330; 461; 497; 575; 599-601
610; 611 replace, 67; 193; 313; 316; 396; 461; 494; 495;
scripts/make_binary_distribution, 85; 95 497
т tar, 54; 81; 85; 91; 92; 94; 109; 110; 114-119;
131; 136; 171; 178; 179; 194; 195; 198;
Тип 354; 374; 375; 393
BIT, 43; 61
DATE, 20; 25; 45; 46; 69; 157; 165; 166; 361; Ф
585;587 Файл
DATETIME, 20; 25; 44; 46; 69; 157; 158; 166 my.cnf, 97; 98; 106; 113; 118; 120; 134; 145-
SET, 20; 44; 46; 57-60; 64; 67; 69; 73-75; 147; 154; 167; 174; 206; 207; 209; 218-
124; 150-152; 155; 156; 158; 161; 196; 220; 222; 231; 269; 311; 316; 317; 356;
210; 227; 231; 232; 234; 235; 242; 243; 359; 360; 376; 378; 385; 451; 459; 474;
253; 254; 256; 257; 269; 270; 276; 289; 524-528; 534; 535; 537; 544; 546; 547;
291; 292; 296; 298-300; 304; 305; 309; 550; 552; 561; 603; 610
332; 349; 350; 363; 387-389; 400; 424; my.ini, 97; 98; 134; 206; 459; 524; 525; 527;
428; 432; 434; 443; 445; 476; 477; 518; 528; 535; 537
528; 533;536;537; 539-543; 551; 552; Файловая система
555; 556; 559; 561; 562; 592; 593; 599; ext2, 24; 448
606 ReiserFS, 24; 78; 448
TIMESTAMP, 20; 25; 26; 44; 46; 157; 166; Функция
228; 361; 380; 384; 394; 587; 611 ADD_TO_SET, 44
TINYINT,43;466;507;585 ANY(), 45
Триггер, 37; 65 EVERY(), 45
REMOVE_FROM_SET, 44
У SOME(), 45
Уровень изоляции транзакций, 551; 552
READ COMMITTED, 230; 237; 552 X
READ UNCOMMITTED, 230; 552 Хранимая процедура, 37; 42; 65; 429
REPEATABLE READ, 230; 552
SERIALIZABLE, 58; 158; 230; 552; 553; 557
Научно-популярное издание

Компания MySQL AB

MySQL. Руководство администратора

Верстка Т.Н. Артеменко


Художественный редактор ВТ. Павлютин

Издательский дом "Вильяме".


101509, Москва, ул. Лесная, д. 43, стр. 1.

Подписано в печать 31.03.2005. Формат 70X100/16.


Гарнитура Times. Печать офсетная.
Усл. печ. л. 50,31. Уч.-изд. л. 39,64.
Тираж 3000 экз. Заказ № 1384.

Отпечатано с диапозитивов в ФГУП "Печатный двор"


Министерства РФ по делам печати,
телерадиовещания и средств массовых коммуникаций.
197110, Санкт-Петербург, Чкаловский пр., 15.

Вам также может понравиться