Администрирование баз данных
4.1 Конфигурирование MySQL
4.1.1 Параметры командной строки mysqld
В большинстве случаев управление параметрами mysqld осуществляется при помощи файлов параметров (see section 4.1.2 Файлы параметров `my.cnf').
mysqld
и mysqld.server
считывают параметры из групп mysqld
и server
.
mysqld_safe
считывает параметры из групп mysqld
, server
, mysqld_safe
и
safe_mysqld
. Встроенный сервер MySQL обычно считывает параметры из server
,
embedded
и xxxxx_SERVER
, где xxxxx
- имя приложения.
mysqld принимает следующие параметры командной строки (для получения полного
списка выполните mysqld --help
):
--ansi
- Использовать синтаксис ANSI SQL вместо синтаксиса MySQL (see section 1.9.2 Запуск MySQL в режиме ANSI).
-b, --basedir=path
- Путь к каталогу установки. Все остальные пути обычно определяются относительно этого пути.
--big-tables
- Позволяет использовать наборы результатов большого объема за счет сохранения всех временных файлов в одном. Данный параметр позволяет устранить большинство ошибок 'table full' (таблица переполнена), но замедляет обработку запросов, для которых было бы достаточно таблиц, расположенных в памяти. Начиная с версии 3.23.2 в MySQL эта проблема решается автоматически: память используется для небольших временных таблиц, а при необходимости происходит переключение на таблицы, расположенные на диске.
--bind-address=IP
- IP-адрес, с которым необходимо установить связь.
--console
-
Писать журнал сообщений/ошибок в stderr/stdout даже если
--log-error
указана. На Windows mysqld просто не будет закрывать консольное окно если указана эта опция. --character-sets-dir=path
- Каталог, в котором расположены наборы символов (see section 4.6.1 Набор символов, применяющийся для записи данных и сортировки).
--chroot=path
-
Изменяет корневой каталог программы mysqld во время запуска.
Рекомендуемая мера безопасности для MySQL 4.0 (MySQL 3.23 не вполне в состоянии предоставить
100% измененную среду запуска). Эта опция некоторым образом ограничивает
использование функций
LOAD DATA INFILE
иSELECT ... INTO OUTFILE
. --core-file
-
Записывает файл ядра, если происходит аварийное прекращение работы
mysqld
. В некоторых системах также необходимо указать--core-file-size
для safe_mysqld (see section 4.7.2safe_mysqld
, оболочкаmysqld
). Обратите внимание на то, что в некоторых системах, таких как Solaris, не удастся записать файл ядра, если используется параметр--user
. -h, --datadir=path
- Путь к корневому каталогу базы данных.
--debug[...]=
-
Если MySQL настроен при помощи
--with-debug
, то этот параметр позволяет получить файл трассировки, в котором отражена работаmysqld
(see section D.1.2 Создание трассировочных файлов). --default-character-set=charset
- Задает набор символов, принятый по умолчанию (see section 4.6.1 Набор символов, применяющийся для записи данных и сортировки).
--default-table-type=type
- Задает тип таблиц, принятый по умолчанию (see section 7 Типы таблиц MySQL).
--delay-key-write[= OFF | ON | ALL]
-
Указывает, как на MyISAM
DELAYED KEYS
должен обрабатываться. See section 5.5.2 Настройка параметров сервера. --delay-key-write-for-all-tables; В MySQL 4.0.3 следует использовать
--delay-key-write=ALL
.-
Отмена сброса на диск ключевых буферов для всех таблиц
MyISAM
между записями. See section 5.5.2 Настройка параметров сервера. --des-key-file=filename
-
Задает считывание из файла filename принятых по умолчанию ключей, которые
используются для
DES_ENCRYPT()
иDES_DECRYPT()
. --enable-external-locking (было --enable-locking)
-
Включает блокировку доступа к системе. Обратите внимание на то, что если
этот параметр используется в системе, где функция
lockd
полностью не работает (например, в Linux), это может привести к зависанию mysqld. --enable-named-pipe
- Включает поддержку для именованных каналов (только в NT/Win2000/XP).
-T, --exit-info
- Побитовое маскирование различных флагов, которое применяется для отладки сервера mysqld; не следует использовать этот параметр, если вы хорошо не разбираетесь в том, что именно он делает!
--flush
- Задает сброс на диск всех изменений после каждой команды SQL. Обычно MySQL только направляет все изменения на диск после каждой команды SQL, делегируя управление синхронизацией записи на диск операционной системе (see section A.4.1 Что делать, если работа MySQL сопровождается постоянными сбоями).
-?, --help
- Вывод сокращенной справки и завершение выполнения.
--init-file=file
- Задает считывание команды SQL из файла file при запуске.
-L, --language=...
- Вывод сообщений об ошибках клиента на указанном языке. Может быть задан в виде полного пути (see section 4.6.2 Сообщения об ошибках на языках, отличных от английского).
-l, --log[=file]
- Задает занесение в файл журнала соединений и запросов (see section 4.9.2 Общий журнал запросов).
--log-bin=[file]
- Двоичный журнал обновлений. Сохранение всех запросов, изменяющих данные, в файл. Используется для архивного копирования и репликации. See section 4.9.4 Бинарный журнал обновлений.
--log-bin-index[=file]
- Имя индексного файла для двоичного журнала обновлений. See section 4.9.4 Бинарный журнал обновлений.
--log-error[=file]
- Писать ошибки и сообщения в этот файл. See section 4.9.1 Журнал ошибок.
--log-isam[=file]
-
Заносит в файл журнала все изменения
ISAM
/MyISAM
(используется только при отладкеISAM
/MyISAM
). --log-slow-queries[=file]
-
Заносит в файл журнала все запросы, выполнение которых заняло больше, чем
long_query_time
секунд (see section 4.9.5 Журнал медленных запросов). --log-update[=file]
-
Заносит в файл журнала обновления
file.#
где#
представляет собой уникальный номер, если он не был задан (see section 4.9.3 Журнал обновлений (update)). --log-long-format
-
Заносит в файл журнала обновлений некоторую дополнительную информацию.
Если задано
--log-slow-queries
, то запросы, не использующие индексов, будут заноситься в журнал медленных запросов. --low-priority-updates
-
Операциям по изменению таблиц (
INSERT
/DELETE
/UPDATE
) будет назначен более низкий приоритет, чем операциям выбора. Это также можно реализовать при помощи{INSERT | REPLACE | UPDATE | DELETE} LOW_PRIORITY ...
, чтобы понизить приоритет только одного запроса, или черезSET LOW_PRIORITY_UPDATES=1
, чтобы изменить приоритет в одном потоке (see section 5.3.2 Вопросы блокирования таблиц). --memlock
-
Фиксирует процесс
mysqld
в памяти. Этот параметр работает только в том случае, если ваша система поддерживает системный вызовmlockall()
, например Solaris. Такая мера может быть полезной, если операционная система записываетmysqld
в файл подкачки на диск. --myisam-recover [=параметр[,параметр...]]]
-
Параметр - это любое сочетание
DEFAULT
,BACKUP
,FORCE
илиQUICK
. Если необходимо отключить данную функцию, укажите вместо набора параметров явно""
. Если эта функция используется,mysqld
проверит таблицу на предмет того, была ли она отмечена как сбойная или не была закрыта надлежащим образом (последний вариант действует только в том случае, если был включен параметр--skip-external-locking
). В любом из этих случаевmysqld
произведет полную проверку таблицы. Если таблица была повреждена,mysqld
попытается ее восстановить. Приведенные ниже параметры влияют на работу процесса восстановления.
Перед автоматическим восстановлением таблицы MySQL добавит запись об этом в журнал ошибок. Если необходимо, чтобы восстановление после большинства ошибок осуществлялось без вмешательства пользователя, следует установить параметрыПараметр Описание DEFAULT Аналогично отсутствию каких-либо параметров для функции --myisam-recover
.BACKUP Если во время восстановления таблица данных была изменена, сохраняется резервная копия файла данных `table_name.MYD' под именем `table_name-datetime.BAK'. FORCE Запуск восстановления, даже если будет утрачено более одной строки из файла `.MYD'. QUICK Не проверять строки в таблице, в которых отсутствуют удаленные блоки. BACKUP
иFORCE
. Тогда восстановление будет производиться даже в случае, если некоторые строки будут удалены, но файл данных будет сохраняться в виде резервной копии, поэтому впоследствии всегда можно будет определить, что произошло. --pid-file=path
-
Путь к pid-файлу используется функцией
safe_mysqld
. -P, --port=...
- Номер порта для прослушивания соединений TCP/IP.
-o, --old-protocol
- Использовать протокол 3.20 для совместимости с некоторыми очень старыми клиентами (see section 2.5.5 Модернизация с версии 3.20 до версии 3.21).
--one-thread
- Использовать только один поток (для отладки в системе Linux) (see section D.1 Отладка сервера MySQL).
-O, --set-variable var=option
-
Задает значение для переменной.
--help
- выводит список переменных. Подробное описание всех переменных можно найти в разделеSHOW VARIABLES
этого руководства (see section 4.5.6.4SHOW VARIABLES
). Обратите внимание,--set-variable
морально устарела с версии MySQL 4.0. Просто используйте--var=option
. See section 5.5.2 Настройка параметров сервера. В MySQL 4.0.2 вы можете устанавливать переменную непосредственно с помощью--variable-name=option
, иset-variable
больше не нужна в файлах опций. Если вы хотите ограничить максимальное значение, в которое может быть установлена пемеременная при помощиSET
, определите это значение с помощью опции--maximum-variable-name
See section 5.5.6 Синтаксис командыSET
. Когда переменная будет устанавливаться в какое-либо значение, MySQL автоматически будет корректировать его, чтобы оно оставалось в указананных рамках; также MySQL может немного корректировать установленное значение с тем, чтобы эффективнее использовались внутренние алгоритмы. Раздел по настройке параметров сервера включает информацию по их оптимизации (see section 5.5.2 Настройка параметров сервера). --safe-mode
- Пропуск некоторых этапов оптимизации.
--safe-show-database
-
При использовании этого параметра команда
SHOW DATABASES
выдает только те базы данных, для которых у пользователя есть какие-либо привилегии. Начиная с версии 4.0.2 этот параметр является недействительным и больше ни на что не влияет (его значение установлено по умолчанию), так как в новой версии появилась привилегияSHOW DATABASES
(see section 4.3.1 Синтаксис командGRANT
иREVOKE
). --safe-user-create
-
Когда этот параметр включен, пользователь не может создавать новых
пользователей при помощи команды
GRANT
, если он не имеет привилегииINSERT
для таблицыmysql.user
или для любого столбца этой таблицы. --skip-bdb
- Запретить использование таблиц BDB. Это сэкономит память и может ускорить работу.
--skip-concurrent-insert
-
Отключает возможность одновременного выбора и вставки данных для таблиц
MyISAM
(используется только в том случае, если в этой функции найдена ошибка). --skip-delay-key-write; в MySQL 4.0.3 следует использовать --delay-key-write=OFF
-
Игнорирует параметр
DELAY_KEY_WRITE
для всех таблиц (see section 5.5.2 Настройка параметров сервера). --skip-grant-tables
-
Включение данного параметра приводит к тому, что сервер совсем не
использует систему привилегий - таким образом полный доступ ко всем базам
данных получают все! (Можно дать серверу команду снова использовать
таблицы доступа, запустив
mysqladmin flush-privileges
илиmysqladmin reload
.) --skip-host-cache
- Никогда не использовать кэш имени главного компьютера для быстрого разрешения соответствий имен и IP-адресов, а вместо этого всегда запрашивать DNS-сервер по каждому соединению (see section 5.5.5 Как MySQL использует DNS).
--skip-innodb
- Запретить использование таблиц InnoDB. Это сэкономит память и может ускорить работу.
--skip-external-locking (было --skip-locking)
-
Не использовать средства системных блокировок. Чтобы воспользоваться функциями
isamchk
илиmyisamchk
, необходимо выключить сервер (see section 1.4.3 Насколько стабильным является MySQL?). Обратите внимание на то, что в MySQL версии 3.23 для восстановления или проверки таблицMyISAM
можно использоватьREPAIR
иCHECK
. --skip-name-resolve
- Не производится разрешения имен хостов. Все значения в столбце Host в таблицах привилегий должны быть IP-адресами или значениями localhost (see section 5.5.5 Как MySQL использует DNS).
--skip-networking
-
Прослушивание соединений TCP/IP не производится. Связь с
mysqld
должна осуществляться через сокеты Unix. Этот параметр рекомендуется для систем, в которых разрешены только локальные запросы (see section 5.5.5 Как MySQL использует DNS). --skip-new
- Не использовать новые (возможно, неправильные) операции.
--skip-symlink
-
Не удалять и не переименовывать файлы, на которые указывает файл
symlinked
в каталоге данных. --skip-safemalloc
-
Если MySQL настроен при помощи
--with-debug=full
, все программы будут проверять память на наличие выхода за границы области памяти при каждом заполнении и освобождении памяти. Поскольку такая проверка осуществляется довольно медленно, от нее можно отказаться, воспользовавшись этим параметром. --skip-show-database
-
Не позволяет использовать команду
SHOW DATABASES
, если пользователь не имеет привилегииSHOW DATABASES
. Начиная с версии 4.0.2 этот параметр больше не нужен, поскольку доступ теперь может быть разрешен при помощи привилегииSHOW DATABASES
. --skip-stack-trace
-
Не записывать трассировку стеков. Этот параметр может оказаться полезным,
когда
mysqld
запущен под отладчиком. В некоторых системах данный параметр также необходимо использовать для получения файла ядра (see section D.1 Отладка сервера MySQL). --skip-thread-priority
- Отключает использование приоритетов потока, чтобы уменьшить время ожидания ответа.
--socket=path
-
Файл канала, который используется для локального соединения вместо файла,
принятого по умолчанию,
/tmp/mysql.sock
. --sql-mode=параметр[,параметр[,параметр...]]
-
Параметр может представлять собой любое сочетание из:
REAL_AS_FLOAT
,PIPES_AS_CONCAT
,ANSI_QUOTES
,IGNORE_SPACE
,SERIALIZE
,ONLY_FULL_GROUP_BY
. Если нужно произвести сброс значения, параметр может быть пустым ("")
. Указание всех приведенных выше параметров аналогично использованию--ansi
. При помощи этого параметра можно включать только необходимые режимы SQL (see section 1.9.2 Запуск MySQL в режиме ANSI). --temp-pool
- При указании данного параметра для создаваемых временных файлов будет использоваться ограниченный набор имен вместо создания уникального имени для каждого нового файла. Данная функция предназначена для устранения проблемы ядра Linux, возникающей при создании большого количества новых файлов с разными именами. По старой схеме в Linux как бы происходит 'утечка' памяти, так как она распределяется для кэша каталогов вместо дискового кэша.
--transaction-isolation= { READ-UNCOMMITTED | READ-COMMITTED |
-
REPEATABLE-READ | SERIALIZABLE }
Задает принятый по умолчанию уровень изоляции транзакции (see section 6.7.3 Синтаксис команды
SET TRANSACTION
). -t, --tmpdir=path
-
Путь для временных файлов. Может быть полезен, если принятый по умолчанию
каталог
/tmp
расположен на слишком маленьком диске и не может вместить все временные таблицы. Начиная с MySQL 4.1, эта опция поддержает указание нескольких путей, разделенных двоеточием:
(на Windows - точкой с запятой;
). Эти пути будут использованы в ротации. -u, --user= [user_name | userid]
-
Запуск демона
mysqld
от имени пользователяuser_name
илиuserid
(число). Этот параметр является обязательным при запускеmysqld
в качестве главной программы. Начиная с MySQL 3.23.56 и 4.0.12: Для того, чтобы избежать возможного пробоя в безопасности когда пользователь добавляет опцию--user=root
в один из файлов `my.cnf',mysqld
лишь только будет использовать первую указанную опцию--user
и давать предупреждение если указано множество таких опций. Имейте в виду, что `/etc/my.cnf' и `datadir/my.cnf' могут перекрыть опцию командной строки - таким образом, рекомендовано указывать эту опцию именно в `/etc/my.cnf'. -V, --version
- Вывод информации по версии программы и завершение выполнения.
-W, --log-warnings (было --warnings)
-
Задает запись таких предупреждений, как
Aborted connection...
в файл `.err' (see section A.2.9 Коммуникационные ошибки / Оборванные соединения.
Большая часть значений может быть изменена в процессе работы сервера
с помощью команды SET
. See section 5.5.6 Синтаксис команды SET
.
4.1.2 Файлы параметров `my.cnf'
Начиная с версии 3.22 MySQL может считывать принятые по умолчанию параметры запуска для сервера и клиентов из файлов параметров.
В Unix считывание принятых по умолчанию параметров MySQL производится из следующих файлов:
Имя файла | Назначение |
/etc/my.cnf | Общие параметры |
DATADIR/my.cnf | Параметры для сервера |
defaults-extra-file | Файл, указанный при помощи -defaults-extra-file=# |
~/.my.cnf | Параметры для пользователя |
DATADIR
является каталогом данных MySQL (обычно `/usr/local/mysql/data' для
бинарной установки или `/usr/local/var' для установки из исходных текстов).
Обратите внимание, что это тот каталог, который был задан во время
настройки, а не указанный при помощи --datadir
при запуске mysqld
!
(--datadir
не оказывает влияния на просмотр файлов параметров сервером,
так как их просмотр происходит до обработки аргументов командной строки).
В Windows считывание принятых по умолчанию параметров MySQL производится из следующих файлов:
Имя файла | Назначение |
windows-system-directory\my.ini | Общие параметры |
C:\my.cnf | Общие параметры |
Обратите внимание на то, что в Windows все пути необходимо указывать при
помощи /
вместо \.
Если необходимо использовать \,
то его нужно указать
дважды, так как \
является знаком перехода в MySQL.
MySQL пытается прочитать файлы параметров в указанном выше порядке. Если существует несколько таких файлов, то параметр, указанный в файле, идущем позже, имеет преимущество над таким же параметром, указанным в файле, расположенном ранее. Параметры, указанные в командной строке, обладают более высоким приоритетом по отношению к параметрам, указанным в любом из файлов параметров. Некоторые параметры можно задавать при помощи переменных окружения. Параметры, указанные в командной строке или в файлах параметров, обладают преимуществом по отношению к переменным окружения (see section E Переменные окружения).
Приводим список программ, поддерживающих файлы параметров: mysql
,
mysqladmin
, mysqld
, mysqld_safe
, mysql.server
, mysqldump
, mysqlimport
,
mysqlshow
, mysqlcheck
, myisamchk
и myisampack
.
Любой параметр, который может быть задан в командной строке при запуске
программы MySQL, может быть также задан в файле параметров (без
предваряющего двойного слэша). Чтобы получить список доступных параметров,
следует запустить программу с параметром --help
.
Файлы параметров могут содержать строки следующего вида:
#comment
- Строки комментариев начинаются с символа `#' или `;'. Пустые строки игнорируются.
[group]
- группа представляет собой имя программы или группы, для которой необходимо задать параметры. Любые параметры или строки, задающие значения переменных, которые указаны после строки группы, будут относиться к названной группе, пока не закончится файл параметров или же не будет указана другая строка группы.
option
-
Эквивалент
--option
в командной строке. option=value
-
Эквивалент
--option=value
в командной строке. set-variable = variable=value
-
Эквивалент
--set-variable variable=value
в командной строке. Данный синтаксис необходимо использовать для задания переменныхmysqld
. Заметьте,--set-variable
не используется с MySQL 4.0. Просто используйте--variable=value
.
Группа client
обеспечивает возможность задавать параметры, относящиеся ко
всем клиентам MySQL (кроме самого mysqld
). Эта группа великолепно подходит
для указания пароля, используемого при подсоединении к серверу (но при
этом следует убедиться, что разрешение на чтение и запись этого файла есть
только у вас).
Обратите внимание на то, что для параметров и значений все введенные перед ними и после них пробелы автоматически удаляются. В строках значений можно использовать такие экранирующие секвенции: `\b', `\t', `\n', `\r', `\\' и `\s' (`\s' - это пробел).
Пример типичного глобального файла параметров:
[client] port=3306 socket=/tmp/mysql.sock [mysqld] port=3306 socket=/tmp/mysql.sock set-variable = key_buffer_size=16M set-variable = max_allowed_packet=1M [mysqldump] quick
Пример типичного файла параметров пользователя:
[client] # Указанный пароль будет направлен всем стандартным клиентам MySQL password=my_password [mysql] no-auto-rehash set-variable = connect_timeout=2 [mysqlhotcopy] interactive-timeout
Если у вас дистрибутив исходного кода, то примеры конфигурационных файлов
с именами `my-xxxx.cnf' можно найти в каталоге `support-files'. В случае
бинарного дистрибутива следует обратиться к каталогу `DIR/support-files',
где DIR
- имя каталога установки MySQL (обычно `/usr/local/mysql'). На
данный момент там приведены примеры файлов конфигурации для малых,
средних, больших и очень больших систем. Чтобы поэкспериментировать с
файлом, можно скопировать `my-xxxx.cnf' в свой домашний каталог
(переименуйте копию в `.my.cnf').
Все поддерживающие файлы параметров клиенты MySQL принимают следующие параметры:
Параметр | Описание |
--no-defaults | Не читать информацию из файлов параметров. |
--print-defaults | Вывести имя программы и все параметры, которые ей передаются. |
--defaults-file=full-path-to-default-file | Использовать только указанный файл конфигурации. |
--defaults-extra-file=full-path-to-default-file | Прочитать этот файл конфигурации после глобального файла конфигурации, но перед файлом конфигурации пользователя. |
Обратите внимание на то, что указанные выше параметры должны идти первыми
в командной строке! Однако параметр --print-defaults
может использоваться
сразу после команд --defaults-xxx-file
.
Примечание для разработчиков: обработка файла параметров происходит следующим образом: все совпадающие параметры (т.е. параметры в соответствующих группах) обрабатываются перед любыми аргументами командной строки. Этот алгоритм хорошо подходит для программ, которые в случае, если один и тот же параметр указывается несколько раз, используют последний экземпляр параметра. Если же вы работаете со старой программой, которая считывает заданные несколько раз параметры указанным образом, но не читает файлы параметров, необходимо добавить только две строки, чтобы у нее появилась эта возможность. Чтобы увидеть, как это делается, достаточно ознакомиться с исходным кодом любого стандартного клиента MySQL.
В скриптах оболочки для анализа файлов config
можно использовать команду
`my_print_defaults':
shell> my_print_defaults client mysql --port=3306 --socket=/tmp/mysql.sock --no-auto-rehash
Приведенные выше выходные данные содержат все параметры для групп client
и
mysql
.
4.1.3 Установка нескольких серверов на один компьютер
В некоторых случаях необходимо, чтобы на одном компьютере работало
несколько различных серверов mysqld
: например, если нужно запустить для
тестирования новую версию MySQL совместно со старой версией, которая
находится в работе, или когда разным пользователям нужно предоставить
доступ к различным серверам mysqld
, с которыми они умеют обращаться
самостоятельно.
Один из способов запустить новый сервер -- указать ему другой канал и порт, например, таким образом:
shell> MYSQL_UNIX_PORT=/tmp/mysqld-new.sock shell> MYSQL_TCP_PORT=3307 shell> export MYSQL_UNIX_PORT MYSQL_TCP_PORT shell> scripts/mysql_install_db shell> bin/safe_mysqld &
Приложение, в котором описаны переменные окружения, включает список других
переменных окружения, которые можно использовать для управления mysqld
(see section E Переменные окружения).
В приведенном выше примере представлен грубый быстрый метод, который обычно применяется для тестирования. Преимуществом данного метода является то, что все соединения, которые устанавливаются в указанной выше оболочке, автоматически направляются на новый запущенный сервер!
Если работать с несколькими серверами необходимо постоянно, то нужно создать файл параметров для каждого сервера (see section 4.1.2 Файлы параметров `my.cnf'). В скрипте запуска, который выполняется при каждой загрузке, следует указать оба сервера:
safe_mysqld --defaults-file=path-to-option-file
Для серверов должны быть различными по крайней мере следующие параметры:
- port=#
- socket=path
- pid-file=path
Приведенные ниже параметры, если они используются, также должны различаться:
- log=path
- log-bin=path
- log-update=path
- log-isam=path
- bdb-logdir=path
- shared-memory-base-name (Новое в MySQL 4.1)
Если требуется увеличить производительность, необходимо также задать разные значения для следующих параметров:
- tmpdir=path
- bdb-tmpdir=path
See section 4.1.1 Параметры командной строки mysqld
.
Начиная с MySQL 4.1, в tmpdir
могут быть указаны несколько путей, разделенных
двоеточием :
(точкой с запятой на Windows ;
). Эти пути будут
использованы в ротации. Эта функция может быть использована для того, чтобы распределить
данные между разными физическими дисками.
Если производится установка бинарной версии MySQL (файлы .tar), которая
запускается из ./bin/safe_mysqld
, то в большинстве случаев единственными
параметрами, которые необходимо добавить/изменить, являются аргументы
socket
и port
для safe_mysqld
.
See section 4.1.4 Запуск нескольких серверов MySQL на одном компьютере.
4.1.4 Запуск нескольких серверов MySQL на одном компьютере
Иногда возникают обстоятельства, когда необходимо запустить несколько серверов на одном компьютере. Например, может понадобиться произвести тестирование новой версии MySQL, не изменяя текущей установки программы. Или еще вариант: вы являетесь поставщиком услуг Internet, который хочет предоставить независимые установки MySQL для различных клиентов.
Если необходимо запустить несколько серверов, то проще всего
скомпилировать серверы с различными портами TCP/IP и файлами сокетов (see section 4.7.3 Mysqld_multi
, программа для управления множеством серверов MySQL).
Предположим, что существующий сервер настроен на принятые по умолчанию
номер порта и файл сокета. Настроим новый сервер при помощи команды
configure
следующим образом:
shell> ./configure --with-tcp-port=port_number \ --with-unix-socket-path=file_name \ --prefix=/usr/local/mysql-3.22.9
Здесь port_number
и file_name
должны отличаться от принятого по умолчанию
номера порта и пути файла сокета, а значение --prefix
должно указывать
каталог установки, который отличается от того, в котором установлен
текущий MySQL.
Проверить сокет, используемый установленным на данный момент сервером MySQL, можно при помощи следующей команды:
shell> mysqladmin -h hostname --port=port_number variables
Обратите внимание: если указать ``localhost
'' как имя удаленного компьютера,
mysqladmin
по умолчанию будет использовать сокеты Unix вместо TCP/IP.
В MySQL 4.1 вы также можете указать протокол, который надлежит использовать с помощью опции
--protocol=(TCP | SOCKET | PIPE | MEMORY)
.
Если на используемом порту находится сервер MySQL, то будет выдан список самых важных настраиваемых переменных в MySQL, включая имя сокета.
Повторно компилировать новый сервер MySQL нет необходимости, его просто
нужно запустить с другими параметрами для порта и сокета. Используемые
порт и сокет можно изменить, указав их как параметры запуска для
safe_mysqld
:
shell> /path/to/safe_mysqld --socket=file_name --port=port_number
Модуль mysqld_multi
может также в качестве аргумента принимать safe_mysqld
(или mysqld
) и передавать параметры из файла конфигурации для safe_mysqld
и дальше для mysqld
.
Если новый сервер запускается на том же каталоге базы данных, что и другой
сервер с включенной записью в журналы, необходимо также указать имена
файлов журналов для safe_mysqld
при помощи параметров --log
, --log-update
или --log-slow-queries
. Иначе оба сервера могут попытаться осуществить
запись в один и тот же файл журнала.
Предупреждение: обычно нельзя допускать, чтобы два сервера одновременно заносили данные в одну и ту же базу данных! Если ваша операционная система не поддерживает безотказную блокировку доступа, это может привести к возникновению неприятных сюрпризов!
Если для второго сервера понадобится использовать другой каталог базы
данных, можно воспользоваться параметром --datadir=path
для safe_mysqld
.
Обратите внимание: запуск нескольких серверов MySQL (mysqlds
) на различных
компьютерах с доступом к одному каталогу данных через сетевую файловую
систему обычно не приводит ни к чему хорошему! Проблема состоит в том,
что сетевая файловая система становится узким местом для передачи данных.
Она не предназначена для такого использования. И даже в этом случае
придется искать решение, которое позволит обеспечить отсутствие конфликтов
между двумя или более модулями mysqld
. На данный момент не существует
платформы, которая обеспечивает на 100% надежную блокировку доступа к
файлам (обычно демон lockd
) во всех возможных ситуациях. Кроме того,
существует еще одна опасность при использовании сетевой файловой системы:
эта система может еще больше усложнить работу программы lockd
. Поэтому
лучше смотреть на вещи проще и забыть об этой идее. Оптимальным решением
будет использование одного компьютера с несколькими центральными
процессорами и с операционной системой, которая эффективно управляет
потоками.
Если нужно подсоединиться к серверу MySQL, который работает с портом, отличным от того, с которым откомпилирован ваш клиент, можно воспользоваться одним из следующих методов:
-
Запустите клиент с параметрами
--host 'hostname' --port=port_number
, чтобы подсоединиться через TCP/IP, или[--host localhost --socket=file_name]
, чтобы подсоединиться через сокет Unix. -
Запускайте ваш клиент с
--protocol=tcp
для подключения по TCP/IP и--protocol=socket
для подключения через сокет Unix. - В своей программе на языке C или Perl можно задать аргументы порта или сокета при подсоединении к серверу MySQL.
-
При использовании модуля Perl
DBD::mysql
можно прочитать параметры из файлов параметров MySQL (see section 4.1.2 Файлы параметров `my.cnf').$dsn = "DBI:mysql:test;mysql_read_default_group=client; mysql_read_default_file=/usr/local/mysql/data/my.cnf" $dbh = DBI->connect($dsn, $user, $password);
-
Задайте переменные окружения
MYSQL_UNIX_PORT
иMYSQL_TCP_PORT
, чтобы указать на сокет Unix и порт TCP/IP до запуска клиентов. Если обычно используются конкретные сокет или порт, команды для задания этих переменных окружения необходимо поместить в свой файл `.login' (see section E Переменные окружения). - Укажите принятые по умолчанию сокет и порт TCP/IP в файле `.my.cnf' в своем домашнем каталоге (see section 4.1.2 Файлы параметров `my.cnf').
4.2 Общие проблемы безопасности и система привилегий доступа MySQL
MySQL имеет развитую, но нестандартную систему обеспечения безопасности и привилегий доступа. В этом разделе дается описание ее работы.
4.2.1 Общие принципы обеспечения безопасности
С данным разделом должны ознакомиться все, кто использует MySQL на компьютерах, подключенных к Internet, - чтобы избежать наиболее распространенных ошибок, приводящих к нарушению безопасности системы.
При обсуждении вопросов безопасности мы акцентируем внимание на необходимости защиты всего серверного хоста (а не одного лишь сервера MySQL) от всех возможных типов атак: перехвата, внесения изменений, считывания и отказа в обслуживании. Данный раздел не охватывает всех аспектов готовности к работе и отказоустойчивости.
Используемая в MySQL система безопасности для всех подключений, запросов и иных операций, которые может пытаться выполнить пользователь, базируется на списках контроля доступа ACLs (Access Control Lists). Обеспечивается также некоторая поддержка SSL-соединений между клиентами и серверами MySQL. Многие из рассматриваемых здесь концепций не относятся исключительно к MySQL; те же общие соображения применимы практически ко всем приложениям.
При работе в MySQL старайтесь следовать приведенным ниже инструкциям:
-
Не предоставляйте никому (за исключением пользователя
mysql
под именемroot
) доступа к таблицеuser
в базе данныхmysql
! Это чрезвычайно важно. В MySQL зашифрованный пароль является реальным паролем. Узнав пароль, занесенный в таблицуuser
, и имея доступ к удаленному компьютеру, занесенному в соответствующую учетную запись, войти в систему под именем зарегистрированного владельца пароля легко может кто угодно. -
Изучите систему прав доступа MySQL. Для управления доступом к MySQL
служат команды
GRANT
иREVOKE
. Предоставляйте ровно столько прав, сколько необходимо, и не больше. Никогда не предоставляйте права всем хостам. Полезно проводить следующие контрольные проверки:-
Выполните команду
mysql -u root
. Если удается успешно установить соединение с сервером без получения запроса пароля, значит, у вас имеются проблемы. Это означает, что кто угодно может подсоединиться к вашему серверу MySQL как клиент MySQL под именемroot
, получая таким образом право неограниченного доступа! Проанализируйте инструкцию по инсталляции MySQL, обращая особое внимание на ту часть, которая касается задания пароля пользователяroot
. -
С помощью команды
SHOW GRANTS
проверьте, кто и к каким ресурсам имеет доступ. Воспользуйтесь командойREVOKE
, отмените права доступа, которые не являются необходимыми.
-
Выполните команду
-
Не храните в базе данных незашифрованных паролей. Если злоумышленнику
удастся получить доступ на ваш компьютер, то в его руках окажется
полный список паролей, которыми он может воспользоваться. Применяйте
для шифрования
MD5()
,SHA1()
или другие односторонние хеш-функции. - Не используйте в качестве пароля слова из словарей. Для взлома такого рода паролей имеются специальные программы. Даже слова типа ``xfish98'' - это очень плохие пароли. Куда лучше ``duag98'': здесь используется то же слово ``fish'', но при этом буквы в нем заменены ближайшими к ним слева буквами клавиатуры QWERTY. Еще один метод - составить парольное слово из первых букв слов какого либо словосочетания, например ``Mhall'' - по фразе ``Mary had a little lamb.'' Такой пароль легко запоминается и его легко вводить. А вот разгадать его тому, кто не знает ключевой фразы, будет непросто.
- Приобретите брандмауэр. Эта мера обеспечит защиту как минимум от половины всех видов несанкционированного использования любого ПО, с которым вы работаете. Разместите MySQL за брандмауэром или в демилитаризованной зоне (demilitarised zone - DMZ). Полезно проводить следующие контрольные проверки:
-
Попробуйте просканировать ваши порты из Internet с помощью
утилиты типа
nmap
. MySQL использует по умолчанию порт 3306. Этот порт должен быть недоступен с неблагонадежных компьютеров. Еще один простой способ проверить, открыт или нет ваш MySQL-порт, - попытаться выполнить с какой либо удаленной машины следующую команду, гдеserver_host
- имя хоста, на котором установлен ваш сервер MySQL:shell> telnet server_host 3306
Если соединение будет установлено, и вы получите какие-либо бессмысленные символы, это будет означать, что порт открыт, и его нужно закрыть на брандмауэре или маршрутизаторе (если, конечно, нет действительно веских причин держать его открытым). Если жеtelnet
просто зависнет или в подсоединении будет отказано, тогда все в порядке: порт заблокирован. -
Не доверяйте никаким данным, которые вводят пользователи. Возможны
попытки перехитрить вашу программу путем ввода последовательностей
специальных или экранированных символов в веб-формы, URL-ы или любое
приложение, созданное вами. Убедитесь, что защита вашего приложения не
будет нарушена, если пользователь введет что-нибудь типа "
'; DROP DATABASE mysql;
''. Это крайний случай, но действия хакеров, использующих подобную технологию, могут привести к потере информации и появлению брешей в системе безопасности, если вы не готовы к ним. Не следует также забывать о необходимости проверки цифровых данных (распространенной ошибкой является защита только строк). Некоторые полагают, что если в базе данных хранятся только открытые данные, то в ее защите нет необходимости. Это неверно. Такие базы могут стать объектом успешных атак типа отказа от обслуживания. Простейший способ защиты от взломов такого типа - заключать числовые константы в кавычки:SELECT * FROM table WHERE ID='234'
, а неSELECT * FROM table WHERE ID=23
4. MySQL автоматически преобразует эту строку в число и выбросит из нее все нецифровые символы. Полезно проводить следующие контрольные проверки:-
Для всех веб-приложений:
- Попробуйте ввести во все ваши веб-формы одинарные и двойные кавычки - `'' и `"'. Если MySQL выдаст любое сообщение об ошибке, немедленно разберитесь, в чем дело.
-
Попробуйте видоизменять динамические URL, добавляя в них
%22
(`"'),%23
(`#'), и%27
(`''). - Попробуйте модифицировать типы данных в динамических URL - замените числовые на символьные, используя символы из предыдущих примеров. Ваше приложение должно быть устойчиво к подобного рода атакам.
- Попробуйте вводить в числовые поля вместо цифр буквы, пробелы и специальные символы. Ваше приложение должно либо удалять их до передачи в MySQL, либо выдавать сообщение об ошибке. Пропускать в MySQL значения без проверки очень опасно!
- Проверяйте размер данных перед тем, как они будут переданы в MySQL.
- При подключении приложения к базе данных лучше использовать имя пользователя, отличное от того, которое вы используете для целей администрирования. Не предоставляйте своим приложениям больше прав доступа, чем это необходимо.
-
Пользователям PHP:
- Проверьте функцию
addslashes()
. Что касается PHP 4.0.3, то в нем имеется функцияmysql_escape_string()
, базирующаяся на функции с тем же именем из MySQL C API.
- Проверьте функцию
-
Пользователям MySQL C API:
- Проверьте API-вызов
mysql_real_escape_string()
.
- Проверьте API-вызов
-
Пользователям MySQL++:
- Проверьте такие модификаторы, как
escape
иquote
, - для потоков запросов.
- Проверьте такие модификаторы, как
-
Пользователям Perl DBI:
- Проверьте метод
quote()
или используйте для проверки заполнители.
- Проверьте метод
-
Пользователям Java JDBC:
- Используйте для проверки объект
PreparedStatement
и символы-заполнители.
- Используйте для проверки объект
-
Для всех веб-приложений:
- Не передавайте по Internet открытые (незашифрованные) данные. Они могут оказаться у кого угодно, имеющего достаточно времени и возможностей для того, чтобы перехватить их и использовать в своих целях. Используйте вместо этого протоколы с шифрованием данных, такие как SSL и SSH. MySQL, начиная с версии 4.0.0, поддерживает собственные SSL-соединения. Пересылка по SSH (SSH Port Forwarding) может быть использована для создания туннеля передачи данных с шифрованием и сжатием.
-
Научитесь пользоваться утилитами
tcpdump
иstrings
. В большинстве случаев проверить, являются ли потоки данных MySQL зашифрованными, можно с помощью команды, подобной той, которая приведена ниже:shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings
(Она работает под Linux, и будет, с незначительными изменениями, работать под другими системами.) Предупреждение: если вы не видите данных, это еще не гарантирует того, что они зашифрованы. Если требуется высокий уровень безопасности, обратитесь к экспертам в этой области.
4.2.2 Как обезопасить MySQL от хакеров
При подключении к серверу MySQL используется, как правило, пароль. По линии связи пароль не передается в виде открытого текста, но алгоритм шифрования не очень сложный. Толковый хакер, если ему удастся перехватить трафик между клиентом и сервером, при определенной настойчивости может взломать пароль. Поэтому если связь между клиентом и сервером осуществляется по ненадежной сети, для шифрования связи следует использовать SSH-туннель.
Вся остальная информация передается в текстовом виде и может быть
прочитана кем угодно, кто в состоянии отлеживать подключение. Если это вас
беспокоит, можно воспользоваться протоколом со сжатием данных (в MySQL
3.22 и последующих версиях), что значительно затруднит подобные действия.
Чтобы еще более повысить безопасность связи, следует использовать протокол
ssh
. Open source
-клиент ssh
доступен на веб-сайте http://www.openssh.org/,
а коммерческий ssh
-клиент можно получить на веб-сайте
http://www.ssh.com/. С помощью такого протокола можно обеспечить
зашифрованную связь по протоколу TCP/IP между сервером MySQL и клиентом
MySQL.
Если вы используете MySQL 4.0, то можете также использовать предусмотренную в этой версии поддержку протокола OpenSSL. Обратитесь к разделу See section 4.3.9 Использование безопасных соединений.
Для обеспечения безопасности MySQL-системы необходимо строго придерживаться следующих рекомендаций:
-
У всех пользователей MySQL должны быть пароли. Для приложений
клиент/сервер является общепринятым, что клиент может указывать любое
имя пользователя, но если для
other_user
не задан пароль, то кто угодно может зайти под любым именем, просто введяmysql -u other_user db_name
. Чтобы этого избежать, можно изменить пароль для всех пользователей, отредактировав скриптmysql_install_db
перед запуском приложения, или только пароль дляroot
-пользователя MySQL, как это показано ниже:shell> mysql -u root mysql mysql> UPDATE user SET Password=PASSWORD('new_password') WHERE user='root'; mysql> FLUSH PRIVILEGES;
-
Не запускайте демон MySQL от имени пользователя Unix
root
. Это очень опасно, потому что любой пользователь, имеющий привилегиюFILE
, будет в состоянии создавать файлы как пользовательroot
(например~root/.bashrc
). Чтобы предотвратить это,mysqld
откажется запускаться от имени пользователяroot
, если это не будет задано напрямую с помощью опции--user=root
. В то же времяmysqld
может быть запущена от имени обычного непривилегированного пользователя. Можно также, в целях еще большего укрепления безопасности, создать новый аккаунт Unix-пользователяmysql
. При запускеmysqld
от имени другого пользователя Unix у вас отпадает необходимость заменять имя пользователяroot
в таблицеuser
, так как имена пользователя в MySQL не имеют ничего общего с аккаунтами пользователей Unix. Для запускаmysqld
от имени другого пользователя Unix добавьте в группу[mysqld]
файла опций `/etc/my.cnf' или файла опций `my.cnf', находящегося в каталоге данных сервера, строкуuser
, задающую имя пользователя. Например:[mysqld] user=mysql
В результате сервер будет запущен от имени назначенного пользователя, независимо от того, производится запуск вручную или посредствомsafe_mysqld
илиmysql.server
. Для получения дополнительной информации обратитесь к разделу See section A.3.2 Запуск MySQL от обычного пользователя. -
Откажитесь от поддержки символических ссылок на таблицы (ее можно
запретить с помощью опции
--skip-symlink
). Это особенно важно в том случае, если вы запускаетеmysqld
от имени пользователяroot
, поскольку у того, кто имеет право доступа для записи в каталоги данныхmysqld
, появляется возможность стереть любой файл в системе! Обратитесь к разделу See section 5.6.1.2 Использование символических ссылок для таблиц. - Удостоверьтесь, что пользователь Unix, от имени которого запускается mysqld, является единственным пользователем, имеющим привилегии чтения/записи в директории базы данных.
-
Не предоставляйте привилегии
PROCESS
всем пользователям. Командаmysqladmin processlist
выводит текст запросов, обрабатываемых в данный момент. Следовательно, любой пользователь, имеющий право на выполнение этой команды, получает возможность прочитать, например, такой запрос другого пользователя, какUPDATE
userSET password=PASSWORD('not_secure')
.mysqld
резервирует добавочное подключение для пользователей, имеющих привилегиюPROCESS
, так что пользователь MySQL под именемroot
может подключиться и осуществлять контроль даже в том случае, когда все обычные подключения заняты. -
Не предоставляйте привилегии
FILE
всем пользователям. Любой пользователь, имеющий такую привилегию, может записать в любом месте файловой системы файл с привилегиями демонаmysqld
! Чтобы обеспечить здесь хоть минимальную защиту, все файлы создаваемые с помощью командыSELECT ... INTO OUTFILE
, сделаны общедоступными для записи, но перезаписать существующие файлы нельзя. ПривилегияFILE
может быть также использована для чтения любого файла, доступного пользователю Unix, от имени которого запускается сервер. Можно также прочитать любой файл в текущую базу данных. Это может быть использовано в корыстных целях. Возможно, например, с помощью командыLOAD DATA
загрузить `/etc/passwd' в таблицу и прочесть ее позже с помощьюSELECT
. - Если вы не доверяете своему DNS-серверу, используйте в таблицах привилегий вместо имен хостов IP-адреса. В любом случае следует очень осторожно относиться к внесению в таблицы привилегий записей, в которых значения имени хоста содержат шаблонные символы!
-
Чтобы ограничить число подключений, доступных для отдельного
пользователя, можно в
mysqld
задать значение переменнойmax_user_connections
.
4.2.3 Опции запуска mysqld
, относящиеся к безопасности
К безопасности имеют отношение следующие опции mysqld
:
--local-infile[=(0|1)]
-
При установке опции
--local-infile=0
теряется возможность выполнять командуLOAD DATA LOCAL INFILE
. --safe-show-database
-
Если установлена эта опция, команда
SHOW DATABASES
возвращает только те базы данных, для которых пользователь имеет какую-либо привилегию. Начиная с версии 4.0.2 эта опция отменена и не служит ни для чего (она включена по умолчанию), т.к. сейчас у нас имеется привилегияSHOW DATABASES
. Обратитесь к разделу See section 4.3.1 Синтаксис командGRANT
иREVOKE
. --safe-user-create
-
При установке этой опции пользователь не может создавать новых
пользователей с помощью команды
GRANT
, если у него отсутствует привилегияINSERT
для таблицыmysql.user
. Чтобы предоставить пользователю доступ именно для создания новых пользователей с теми привилегиями, которые он имеет право предоставлять, для этого пользователя следует установить следующую привилегию:mysql> GRANT INSERT(user) ON mysql.user TO 'user'&hacute;ostname';
Задание такой привилегии гарантирует, что этот пользователь не сможет непосредственно вносить изменения ни в одном из столбцов привилегий, а для предоставления привилегий другим пользователям должен будет использовать командуGRANT
. --skip-grant-tables
-
Установка этой опции запрещает серверу вообще использовать систему
привилегий. Это открывает кому бы то ни было полный доступ ко всем базам
данных! (После запуска сервера можно заставить его снова использовать
таблицы привилегий с помощью команды mysqladmin
flush-privileges
илиmysqladmin reload
.) --skip-name-resolve
-
При установке данной опции имена хостов не разрешены. Все значения в
столбцах
Host
таблиц привилегий должны быть либо IP-адресами, либоlocalhost
. --skip-networking
-
Не разрешает осуществлять подсоединений по протоколу TCP/IP через сеть
(данная опция запрещает такие подсоединения). Все подсоединения к
mysqld
должны осуществляться посредством сокетов Unix. Для MySQL старше 3.23.27 эта опция непригодна для систем, в которых используются MIT-потоки, так как MIT-потоки на тот момент не поддерживали сокеты Unix. --skip-show-database
-
Разрешает выполнение команды
SHOW DATABASES
только в том случае, если пользователь имеет привилегиюSHOW DATABASES
. Начиная с версии 4.0.2 в этой опции больше нет необходимости, т.к. теперь доступ может предоставляться избирательно с помощью привилегииSHOW DATABASES
.
4.2.4 Вопросы безопасности, относящиеся к команде LOAD DATA LOCAL
Чтобы решить проблемы безопасности, которые могут возникнуть при
использовании команды LOAD DATA LOCAL
,в MySQL 3.23.49 и MySQL 4.0.2 были
добавлены новые опции.
При поддержке этой команды могут возникнуть две проблемы:
Первая: поскольку чтение файла инициируется сервером, теоретически имеется возможность создать ``доработанный'' при помощи патча сервер MySQL, способный читать любые файлы на клиентской машине, к которой текущий пользователь имеет доступ для чтения, в то время, когда клиент направляет запрос к таблице.
Вторая: в веб-среде, в которой подсоединение клиентов осуществляется с
веб-сервера, пользователь может использовать команду LOAD DATA LOCAL
для
чтения любых файлов, к которым процесс веб-сервера имеет доступ для чтения
(если предположить, что пользователь может выполнять на сервере SQL любые
команды).
Эти проблемы решаются с помощью двух следующих исправлений:
Если вы конфигурируете MySQL без опции --enable-local-infile
, то команда
LOAD DATA LOCAL
будет запрещена для всех клиентов, если, конечно, они не
будут вызывать mysql_options (... MYSQL_OPT_LOCAL_INFILE, 0)
. Обратитесь
к разделу See section 8.4.3.39 mysql_options()
.
В случае клиента mysql, LOAD DATA LOCAL
может быть разблокирована заданием
опции --local-infile[=1]
или заблокирована с помощью опции
--local-infile=0
.
По умолчанию все MySQL-клиенты и библиотеки компилируются с опцией
--enable-local-infile
для обеспечения совместимости с MySQL 3.23.48 и
более старыми версиями.
Блокировку всех команд LOAD DATA LOCAL
на MySQL-сервере можно осуществить
путем запуска mysqld
с опцией --local-infile=0
.
В случае, если команда LOAD DATA LOCAL INFILE
заблокирована на сервере или
клиенте, вы получите следующее сообщение об ошибке (1148):
The used command is not allowed with this MySQL version
4.2.5 Функции, выполняемые системой привилегий
Основной функцией системы привилегий MySQL является аутентификация
пользователя, подключающегося с указанного хоста, и ассоциирование его с
привилегиями базы данных, такими как SELECT
, INSERT
, UPDATE
и DELETE
.
К дополнительным функциональным возможностям системы привилегий относятся
следующие: возможность обслуживания анонимного пользователя и
предоставление привилегий для таких специфических для MySQL функций, как
LOAD DATA INFILE
и функции администрирования.
4.2.6 Как работает система привилегий
Система привилегий MySQL обеспечивает пользователям возможность выполнять только те действия, которые им разрешены в соответствии с их обязанностями. Когда вы подсоединяетесь к серверу MySQL, ваша личность устанавливается по имени хоста, с которого вы подсоединяетесь, и имени пользователя, которое вы указываете. Система предоставляет привилегии в соответствии с вашей личностью и тем, что вы хотите делать.
MySQL идентифицирует пользователя как по имени хоста, так и по имени
пользователя, т.к. нет оснований полагать что данное имя пользователя
принадлежит во всей Сети единственному человеку. Например, пользователь
joe
, устанавливающий соединение с office.com
, вовсе не обязательно один и
тот же человек, что и пользователь joe
, подсоединяющийся с elsewhere.com
.
MySQL решает эту проблему, обеспечивая возможность различать
пользователей, подсоединяющихся с различных хостов под одним и тем же
именем пользователя: вы можете предоставлять joe
один набор привилегий,
если он подсоединяется с office.com
, и другой набор привилегий, если joe
подсоединяется с elsewhere.com
.
Управление доступом в MySQL осуществляется в два этапа:
-
Этап 1: сервер проверяет, имеется ли у вас вообще разрешение на
подсоединение.
2item
Этап 2: если таковое имеется, сервер проверяет каждый из ваших
запросов, чтобы убедиться в том, что у вас имеется достаточно
привилегий для его выполнения. Например, если вы пытаетесь выбрать
строки в таблице базы данных или удалить таблицу из базы данных,
сервер в первом случае проверяет, имеется ли у вас для этой таблицы
привилегия
SELECT
, а во втором - имеется ли у вас для этой базы данных привилегияDROP
.
На обеих стадиях управления доступом сервер использует таблицы user
, db
и
host
из базы данных mysql
. Ниже перечислены поля этих таблиц привилегий:
Имя таблицы | 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 | |||
Reload_priv | |||
Shutdown_priv | |||
Process_priv | |||
File_priv |
На втором этапе управления доступом (верификация запросов) сервер может (в
случае, если запрос относится к таблицам базы данных) дополнительно
обратиться к таблицам tables_priv
и columns_priv
. Поля этих таблиц
привилегий перечислены ниже:
Имя таблицы | tables_priv | columns_priv
|
Поля контекста | Host | Host
|
Db | Db
| |
User | User
| |
Table_name | Table_name
| |
Column_name
| ||
Поля привилегий | Table_priv | Column_priv
|
Column_priv | ||
Иные поля | Timestamp | Timestamp
|
Grantor |
Каждая таблица привилегий включает в себя поля контекста и поля привилегий.
Поля контекста определяют область действия каждой из записей в таблицах,
т.е. контекст, к которому имеет отношение та или иная запись. Например,
запись в таблице user
, в полях Host
и User
которой указаны значения
'thomas.loc.gov'
'bob'
, предназначена для аутентификации подсоединений к
серверу с хоста thomas.loc.gov
под именем пользователя bob
. Аналогично
запись в таблице db
, в полях Host
, User
и Db
которой указаны значения
'thomas.loc.gov'
, 'bob'
и 'reports'
, будет использоваться при попытке
пользователя по именем bob
подсоединиться с хоста thomas.loc.gov
и
получить доступ к базе данных reports
. В полях контекста в таблицах
tables_priv
и columns_priv
указаны таблицы или комбинации таблиц/столбцов,
к которым применяется каждая запись.
При контроле доступа сравнение значений в полях Host
осуществляется без
учета регистра. Значения в полях User
, Password
, Db
и Table_name
также
являются независимыми от регистра символов. Значения в поле Column_name
являются независимыми от регистра символов, начиная с MySQL 3.22.12.
В полях привилегий указываются привилегии, предоставляемые записью в таблице, т.е. то, какие операции разрешено выполнять. Сервер формирует полное описание привилегий пользователя, комбинируя информацию, хранящуюся в разных таблицах привилегий. Это осуществляется по правилам, которые описаны в разделе See section 4.2.10 Управление доступом, этап 2: верификация запросов.
Поля контекста - это строковые значения, объявленные, как показано ниже; устанавливаемым по умолчанию значением для каждого из них является пустая строка:
Имя поля | Тип | Примечания |
Host | CHAR(60) | |
User | CHAR(16) | |
Password | CHAR(16) | |
Db | CHAR(64) | (CHAR(60) для таблиц
tables_priv и columns_priv tables)
|
Table_name | CHAR(60) | |
Column_name | CHAR(60) |
В таблицах user
, db
и host
все поля привилегий имеют объявленный тип
ENUM('N','Y')
, т.е. возможно одно из двух значений - 'N'
и 'Y'
, а
устанавливаемым по умолчанию является 'N'
.
В таблицах tables_priv
and columns_priv
поля привилегий объявляются как
SET
:
Имя таблицы | Имя поля | Допустимые элементы набора |
tables_priv
| Table_priv
| 'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter'
|
tables_priv
| Column_priv
| 'Select', 'Insert', 'Update', 'References'
|
columns_priv
| Column_priv
| 'Select', 'Insert', 'Update', 'References'
|
Если кратко, то сервер использует таблицы привилегий следующим образом:
-
Поля контекста таблицы
user
определяют, разрешить входящее подсоединение или отказать в нем. Для разрешенных подсоединений любые привилегии, предоставленные в таблицеuser
, означают глобальные привилегии пользователя (привилегии суперпользователя). Эти привилегии распространяются на все базы данных, размещенные на сервере. -
Таблицы
db
иhost
используются совместно:-
Поля контекста таблицы
db
определяют, каким пользователям, при подсоединении с каких хостов разрешен доступ к каким базам данных. Поля привилегий определяют разрешенные операции. -
Таблица
host
используется в качестве расширения таблицыdb
в случае, если необходимо применить некоторую запись из таблицы db к разным хостам. Например, если вы хотите предоставить пользователю возможность обращаться к базе данных с различных хостов сети, оставьте пустым поле в записи этого пользователя в таблицеdb
, а затем внесите в таблицуhost
запись для каждого из этих хостов. Более подробно данный механизм описан в разделе See section 4.2.10 Управление доступом, этап 2: верификация запросов.
-
Поля контекста таблицы
-
Таблицы
tables_priv
иcolumns_priv
подобны таблицеdb
, но областью их действия является уже уровень таблиц и столбцов, а не баз данных.
Заметим, что привилегии администрирования (RELOAD
, SHUTDOWN
и т.д..)
задаются только в таблице user
. Это связано с тем, что операции
администрирования являются операциями над самим сервером, а не над базами
данных, поэтому не смысла перечислять такие привилегии в других таблицах
привилегий. Фактически для того, чтобы выяснить, имеете ли вы привилегии
выполнять операции администрирования, достаточно обратиться только к
таблице user
.
Привилегия FILE
также задается только в таблице user
. Она не является
привилегией администрирования как таковой, но возможность производить
чтение или запись файлов на серверном хосте не связана с базой данных, к
которой вы получаете доступ.
Сервер mysqld
считывает содержимое таблиц привилегий единожды, при его
запуске. О том, каким образом изменения, вносимые в таблицы привилегий,
вступают в силу, рассказывается в разделе See section 4.3.3 Когда изменения в привилегиях вступают в силу.
При внесении изменений в таблицы привилегий стоит убедиться в том, что
ваши изменения задают привилегии именно так, как задумано вами. Помощь по
диагностике проблем вы найдете в разделе See section 4.2.11 Причины появления ошибок Access denied
("в доступе отказано"). По вопросам, связанным с безопасностью, следует обращаться к разделу See section 4.2.2 Как обезопасить MySQL от хакеров.
Полезным диагностическим инструментом является скрипт mysqlaccess
,
которым Ив Карлье (Yves Carlier) укомплектовал дистрибутив MySQL.
Запустите mysqlaccess
с опцией --help
чтобы посмотреть, как он работает.
Заметим, что mysqlaccess
контролирует доступ, используя только таблицы
user
, db
и host
. Он не проверяет привилегии на уровне таблиц или
столбцов.
4.2.7 Привилегии, предоставляемые MySQL
Информация о привилегиях пользователя хранится в таблицах user
, db
, host
,
tables_priv
и columns_priv
базы данных mysql
(т.е. в базе данных с именем
mysql). Сервер MySQL считывает содержимое этих таблиц во время запуска, и
в случаях, указанных в разделе See section 4.3.3 Когда изменения в привилегиях вступают в силу.
Ниже приведены имена, используемые в данном руководстве для ссылок на привилегии, предоставляемые в MySQL 4.0.2. Здесь же указаны имена табличных столбцов, ассоциированных с каждой из привилегий в таблицах привилегий, наряду с контекстом, в котором эти привилегии имеют силу:
Привилегия | Столбец | Контекст |
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_table_priv | администрирование сервера |
EXECUTE | Execute_priv | администрирование сервера |
FILE | File_priv | доступ к файлам на сервере |
LOCK TABLES | Lock_tables_priv | администрирование сервера |
PROCESS | Process_priv | администрирование сервера |
RELOAD | Reload_priv | администрирование сервера |
REPLICATION CLIENT | Repl_client_priv | администрирование сервера |
REPLICATION SLAVE | Repl_slave_priv | администрирование сервера |
SHOW DATABASES | Show_db_priv | администрирование сервера |
SHUTDOWN | Shutdown_priv | администрирование сервера |
SUPER | Super_priv | администрирование сервера |
Привилегии SELECT
, INSERT
, UPDATE
и DELETE
позволяют выполнять операции
над строками таблиц баз данных.
Для операторов SELECT
привилегия SELECT
требуется только в том случае,
если они действительно извлекают строки из таблицы.. В ряде случае можно
выполнять операторы SELECT
, даже не имея разрешения на доступ ни к одной
базе данных на сервере. Например: клиент mysql
вы можете использовать в
качестве обычного калькулятора:
mysql> SELECT 1+1; mysql> SELECT PI()*2;
Привилегия INDEX
позволяет создавать или уничтожать (удалять) индексы.
Привилегия ALTER
позволяет использовать команду ALTER TABLE
.
Привилегии CREATE
и DROP
позволяют создавать новые базы данных и таблицы
или уничтожать (удалять) существующие базы данных и таблицы.
Заметим, что в случае, если пользователю предоставляется привилегия DROP
по отношению к базе данных mysql
, он может уничтожить базу данных, в
которой хранятся привилегии доступа в MySQL!
Привилегия GRANT
позволяет вам предоставлять другим пользователям
привилегии, которыми обладаете вы сами.
Привилегия FILE
дает вам право читать и записывать файлы на сервере с
помощью операторов LOAD DATA INFILE
и SELECT ... INTO OUTFILE
. Любой
пользователь, которому предоставлена такая привилегия, имеет право
прочитать или записать любой файл, который может прочитать или записать
сервер MySQL. Пользователь также может прочитать любой файл в каталоге текущей базы данных.
Однако существующие файлы перезаписывать нельзя.
Остальные привилегии используются для операций администрирования,
выполняемых с помощью программы mysqladmin
. В таблице, приведенной ниже,
для каждой из привилегий администрирования показано, какие команды
mysqladmin
она позволяет выполнять.
Привилегия | Команды, разрешенные обладателю привилегии |
RELOAD | reload , refresh ,
flush-privileges , flush-hosts , flush-logs , and
flush-tables
|
SHUTDOWN | shutdown
|
PROCESS | processlist
|
SUPER | kill
|
Команда reload
заставляет сервер перечитать таблицы привилегий. Команда
refresh
очищает все таблицы, а также открывает и закрывает файлы журналов.
flush-privileges
является синонимом reload
. Остальные команды flush-*
выполняют функции, аналогичные функциям команды refresh
, но с более узкой
областью действия. В некоторых случаях такие команды могут оказаться более
предпочтительными. Например, если вы хотите очистить только системные
журналы, команда flush-logs
лучше, чем refresh
.
Команда shutdown
завершает работу сервера.
Команда processlist
выводит информацию о задачах, выполняющихся на
сервере. Команда kill
уничтожает серверные потоки. Собственные потоки
всегда можно просмотреть или уничтожить, но для отображения потоков,
запущенных другими пользователями, нужна привилегия PROCESS
,а для
уничтожения потоков, запущенных другими пользователями, потребуется
привилегия SUPER
. Обратитесь к разделу See section 4.5.5 Синтаксис команды KILL
.
В общем случае идея предоставлять привилегии только тем пользователям, которым они необходимы, хорошая, но к предоставлению некоторых из них следует относиться особенно внимательно:
-
Привилегия
GRANT
позволяет пользователям передавать свои привилегии другим пользователям. Два пользователя с неодинаковыми привилегиями, имея привилегиюGRANT
, способны объединить свои привилегии. -
Привилегия
ALTER
может быть использована для переименования таблиц и разрушения таким образом всей системы привилегий. -
Привилегия
FILE
может использоваться злонамеренно для считывания любого доступного файла, хранящегося на сервере, или любого файла в каталоге текущей базы данных в таблицу, к содержимому которой можно затем получить доступ с помощью командыSELECT
. -
Привилегия
SHUTDOWN
может использоваться злонамеренно для полного прекращения работы сервера и, таким образом, полного запрещения обслуживания других пользователей. -
Привилегия
PROCESS
может быть использована для просмотра открытого текста запросов выполняющихся в данный момент, включая запросы на установку или изменение паролей. -
Привилегии доступа к базе данных
mysql
могут быть использованы для изменения паролей и другой информации, относящейся к привилегиям доступа. (Пароли хранятся в зашифрованном виде, поэтому злоумышленник не сможет просто прочесть их, чтобы получить пароли в виде обычного текста). Получив доступ к столбцу паролейmysql.user
, любой пользователь может войти на сервер MySQL под именем другого пользователя (имея достаточные привилегии, тот же самый пользователь может заменить пароль на другой).
Есть вещи, которые система привилегий MySQL делать не может:
- Нельзя явно указать, что данному пользователю должен быть закрыт доступ. Т.е. вы не можете явно выбрать пользователя и затем отказать ему в подключении.
- Нельзя указать, что некий пользователь имеет привилегии создавать или удалять таблицы в базе данных, но не имеет привилегий создавать или удалять саму базу данных.
4.2.8 Соединение с сервером MySQL
Обычно для получения доступа к серверу MySQL необходимо сообщить
клиентской программе параметры подсоединения: указать хост, с которым вы
хотите соединиться, ваши имя пользователя и пароль. Например, клиент mysql
можно запустить следующим образом (необязательные аргументы заключены в
квадратные скобки `[' и `]'):
shell> mysql [-h host_name] [-u user_name] [-pyour_pass]
Альтернативной формой опций -h
, -u
, и -p
являются --host=host_name
,
--user=user_name
и --password=your_pass
. Заметим, что между -p
или
--password=
и следующим за ними паролем пробела нет.
Внимание: Указывать пароль в командной строке небезопасно! Любой
пользователь в вашей системе может впоследствии отыскать ваш пароль, введя
команду типа ps auxww
. Обратитесь к разделу See section 4.1.2 Файлы параметров `my.cnf'.
В mysql
используются следующие значения по умолчанию для параметров
подсоединения, пропущенных в командной строке:
-
Значением по умолчанию для имени хоста является
localhost
. - Значением по умолчанию для имени пользователя является ваш Unix-аккаунт.
-
При отсутствии префикса
-p
никакого пароля не указывается.
Таким образом, для Unix-пользователя joe
следующие команды являются
эквивалентными:
shell> mysql -h localhost -u joe shell> mysql -h localhost shell> mysql -u joe shell> mysql
Другие клиенты MySQL ведут себя подобным же образом.
В Unix-системах можно задавать различные значения по умолчанию, которые будут использоваться при соединении с сервером, чтобы избавиться от необходимости каждый раз при вызове клиентской программы вводить их в командной строке. Это можно сделать двумя способами:
-
Параметры подсоединения можно задать в разделе
[client]
файла конфигурации `my.cnf', который находится в вашей домашней директории. Соответствующий раздел этого файла может иметь следующий вид:[client] host=host_name user=user_name password=your_pass
Обратитесь к разделу See section 4.1.2 Файлы параметров `my.cnf'. -
Параметры соединения можно задавать через переменные окружения. Для
mysql
можно задать хост при помощиMYSQL_HOST
. Для задания имени пользователя для MySQL можно использоватьUSER
(это относится только к ОС Windows). Пароль может быть задан с помощьюMYSQL_PWD
(но это небезопасно, см. следующий раздел). Обратитесь к разделу See section E Переменные окружения.
4.2.9 Управление доступом, этап 1: верификация подсоединения
При попытке соединения с сервером MySQL он либо устанавливает соединение, либо отказывает в нем - на основе данных о вашей личности и того, можете ли вы подтвердить их соответствующим паролем. Если нет, сервер полностью отказывает вам в доступе. В противном случае сервер устанавливает соединение, затем переходит ко второму этапу и ожидает запросов.
Личность задается двумя порциями информации:
- хостом, с которого вы подсоединяетесь
- вашим именем пользователя MySQL
Проверка личности осуществляется с помощью трех полей контекста таблицы
user
(Host
, User
и Password
). Сервер устанавливает соединение только в том
случае, если находит в таблице user
запись, в которой имя хоста и имя
пользователя совпадают с введенными вами, и вы указываете правильный
пароль.
Значения в полях контекста таблицы user
могут задаваться следующим
образом:
-
В поле
Host
может указываться имя хоста, либо его IP-адрес, либо'localhost'
для обозначения локального хоста. - В поле Host разрешается использовать шаблонные символы `%' и `_'.
-
Значение
'%'
в полеHost
означает любое имя хоста. -
Пустое значение в поле
Host
означает, что к этой привилегии должна быть добавлена запись в таблицеhost
, совпадающая с заданным именем хоста. Дополнительную информацию по данной теме вы найдете в следующем разделе. -
Начиная с версии MySQL 3.23 для значений в поле в поле
Host
, определенных в виде IP-адресов, можно задавать сетевую маску, указывающую, сколько разрядов адреса будет использоваться для указания номера сети. Например:mysql> GRANT ALL PRIVILEGES ON db.* -> TO david&1acute;92.58.197.0/255.255.255.0';
В этом случае все IP-адреса, для которых выполняется следующее условие:user_ip & netmask = host_ip.
являются разрешенными для подсоединения. В предыдущем примере все IP-адреса в диапазоне от 192.58.197.0 до 192.58.197.255 являются разрешенными для подсоединения к серверу MySQL. -
В поле
User
запрещено использовать шаблонные символы, но пустое значение разрешено, и оно соответствует любому имени. Если запись в таблицеuser
, соответствующая входящему подсоединению, содержит пустое имя пользователя, данный пользователь считается анонимным пользователем (пользователем без имени), а заданное клиентом имя пользователя игнорируется. Это означает, что при всех последующих проверках доступа, осуществляемых на протяжении данного соединения (т.е. на этапе 2), будет использоваться пустое имя пользователя. -
Поле
Password
может быть пустым. Это не означает, что в данном случае подходит любой пароль. Если поле пароля пусто, пользователь должен быть подсоединен без указания какого либо пароля.
Непустые значения в поле Password
представляют собой зашифрованные пароли.
В MySQL пароли не хранятся в виде открытого текста, который может
прочитать кто угодно. Напротив, пароль, который вводится пользователем при
попытке подсоединения, шифруется (с помощью функции PASSWORD()
). В
дальнейшем зашифрованный пароль используется клиентом/сервером в процессе
проверки его правильности (это делается вообще без пересылки пароля во
время подсоединения). Заметим, что с MySQL считает зашифрованный пароль
РЕАЛЬНЫМ паролем, поэтому не следует допускать к нему кого бы то ни было!
В частности, не разрешайте обычным пользователям доступ для чтения к
таблицам в базе mysql
!
Примеры, приведенные ниже, показывают, каким входящим подсоединениям
соответствуют различные комбинации значений, указанных в полях Host
и User
таблицы user
:
Значение в поле Host | Значение в поле User | Подсоединения, которым соответствует запись |
'thomas.loc.gov' | 'fred' | fred , подключающийся с thomas.loc.gov
|
'thomas.loc.gov' | '' | Любой пользователь, подключающийся с thomas.loc.gov
|
'%' | 'fred' | fred , подключающийся с любого хоста
|
'%' | '' | Любой пользователь, подключающийся с любого хоста |
'%.loc.gov' | 'fred' | fred , подключающийся с любого хоста, принадлежащего домену loc.gov
|
'x.y.%' | 'fred' | fred , подключающийся с x.y.net , x.y.com ,x.y.edu , и т.д. (это, по-видимому, бесполезный вариант)
|
'144.155.166.177' | 'fred' | fred , подключающийся с хоста, имеющего IP-адрес 144.155.166.177
|
'144.155.166.%' | 'fred' | fred , подключающийся с любого хоста в подсети 144.155.166 класса C
|
'144.155.166.0/255.255.255.0' | 'fred' | То же самое, что и в предыдущем примере |
Поскольку в IP-адресе, указываемом в поле Host
, могут использоваться
шаблонные символы (например '144.155.166.%'
- данное значение
соответствует всем без исключения хостам указанной подсети), возникает
опасность, что кто-нибудь может попытаться воспользоваться этой
возможностью, указав имя хоста, например, как 144.155.166.somewhere.com
.
Чтобы ``поставить заслон'' таким попыткам, в MySQL не разрешены имена
хостов, начинающиеся с цифр и точки. Другими словами, имени хоста типа
1.2.foo.com
, никогда не найдется соответствия в столбцах Host
таблиц
привилегий. IP-адресу с шаблонными символами может соответствовать только
IP-адрес.
Входящее подсоединение может совпадать с несколькими записями в таблице
user. Например, как было показано выше, подсоединению с thomas.loc.gov by
fred
могут подходить разные записи. Каким образом сервер определяет, какую
из записей использовать, при совпадении с более чем одной из них? Для
этого после считывания таблицы user
во время запуска сервер производит ее
сортировку, а затем, когда пользователь пытается установить соединение,
записи таблицы просматриваются в порядке их упорядочения,. Используется
первая подошедшая запись.
Сортировка таблицы user осуществляется следующим образом. Предположим,
таблица user
имеет следующий вид:
+-----------+----------+- | Host | User | ... +-----------+----------+- | % | root | ... | % | jeffrey | ... | localhost | root | ... | localhost | | ... +-----------+----------+-
При считывании этой таблицы сервер упорядочивает записи, начиная с
наиболее конкретных значений в столбце Host
('%'
в столбце Host
означает
``любой хост'' и является наименее конкретным). Записи с одинаковым
значением в столбце Host
упорядочиваются между собой начиная с наиболее
конкретных значений в столбце User
(пустое значение в столбце User
означает ``любой пользователь'' и является наименее конкретным).
Окончательно отсортированная таблица user
имеет следующий вид:
+-----------+----------+- | Host | User | ... +-----------+----------+- | localhost | root | ... | localhost | | ... | % | jeffrey | ... | % | root | ... +-----------+----------+-
При попытке подсоединения сервер просматривает отсортированные записи и
использует первую подходящую запись. Для подсоединения с localhost
пользователя jeffrey
первыми подходящими записями являются записи со
значением 'localhost'
в столбце Host
. Из них запись с пустым значением
имени пользователя соответствует и имени подсоединяющегося хоста и имени
пользователя. (запись '%'/'jeffrey'
тоже подошла бы, но она -- не первая
подходящая в этой таблице).
Рассмотрим другой пример. Пусть таблица user
имеет вид:
+----------------+----------+- | Host | User | ... +----------------+----------+- | % | jeffrey | ... | thomas.loc.gov | | ... +----------------+----------+-
Отсортированная таблица выглядит следующим образом:
+----------------+----------+- | Host | User | ... +----------------+----------+- | thomas.loc.gov | | ... | % | jeffrey | ... +----------------+----------+-
Для подсоединения пользователя jeffrey
с thomas.loc.gov
подходит первая
запись, в то время как для подсоединения jeffrey
с whitehouse.gov
-
вторая.
Существует распространенное заблуждение: иногда думают, что при поиске
записей для данного имени пользователя, соответствующих определенному
подсоединению, сервер первыми будет использовать записи, в которых этот
пользователь указан явно. Это абсолютно неверно, как и продемонстрировано
в предыдущем примере: для подсоединения пользователя jeffrey
с
thomas.loc.gov
первой подходящей записью является не запись, содержащая
значение 'jeffrey'
в поле User
, а запись, не содержащая имени пользователя
вовсе!
Если у вас возникают проблемы с подсоединением к серверу, выведите
таблицу user
и отсортируйте ее вручную, чтобы увидеть, где
происходит первое совпадение.
Если соединение было успешно, но ваши привилегии - не те, что вы ожидали
увижеть, вы можете использовать функцию CURRENT_USER()
(новшество с
MySQL 4.0.6) чтобы узнать, какой комбинации пользователь/компьютер ваше
соединение соответствует. See section 6.3.6.2 Разные функции.
4.2.10 Управление доступом, этап 2: верификация запросов
После установления соединения сервер приступает к выполнению второго
этапа. Для каждого поступающего запроса сервер проверяет, имеется ли у вас
достаточно привилегий для его выполнения, основываясь при этом на типе
операции, которую вы хотите выполнить. Теперь в действие вступают поля
привилегий в таблицах привилегий. Информация о привилегиях может
находиться в любой из таблиц привилегий - user
, db
, host
, tables_priv
или
columns_priv
. Обработка таблиц привилегий осуществляется с помощью команд
GRANT
и REVOKE
. Обратитесь к разделу See section 4.3.1 Синтаксис команд GRANT
и REVOKE
. Интерес
может представлять раздел See section 4.2.6 Как работает система привилегий, в котором перечислены поля, имеющиеся в каждой из
таблиц привилегий.
Таблица user
предоставляет привилегии глобального характера, и их
применение не зависит от того, в какой базе вы работаете в данный момент.
Например, если таблица user
предоставляет пользователю привилегию DELETE
,
он может удалять строки из любой базы данных на серверном хосте! Иными
словами, привилегии в таблице user
- это привилегии суперпользователя.
Поэтому целесообразно предоставлять привилегии в таблице user
только
суперпользователям, таким как администраторы сервера или администраторы
баз данных. Что касается других пользователей, для их привилегий в таблице
user следует установить значение 'N'
и предоставлять им привилегии только
на уровне баз данных, используя для этого таблицы db
и host
.
Таблицы db
и host
предоставляют привилегии на уровне базы данных. Значения
в полях контекста могут задаваться следующим образом:
-
Шаблонные символы `%' и `_' могут использоваться в полях
Host
иDb
любой таблицы. Если вы хотите использовать символ `_' как часть имени базы данных, укажите его как `\_' в оператореGRANT
. -
Значение
'%'
в колонкеHost
таблицыdb
означает ``любой хост''. Пустое значение в полеHost
таблицыdb
означает ``за дополнительной информацией следует обратиться к таблицеhost
''. -
Значение
'%'
или пустое значение в полеHost
таблицыhost
означает ``любой хост''. -
Значение
'%'
или пустое значение в полеDb
любой из таблиц означает ``любая база данных''. -
Пустое значение в поле
User
любой из таблиц соответствует анонимному пользователю.
Таблицы db
и host
считываются и сортируются при запуске сервера (тогда же,
когда он считывает таблицу user
). Таблица db
сортируется по полям
контекста Host
, Db
и User
, а таблица host
- по полям контекста Host
и Db
.
Как и в случае таблицы user
, при сортировке первыми отбираются наиболее
конкретные значения, а последними - наименее конкретные, а когда сервер
производит поиск совпадающих записей, используется первая совпадающая
запись, которую он находит.
Таблицы tables_priv
и columns_priv
предоставляют привилегии соответственно
на уровне таблиц и столбцов. Значения в полях контекста задаются следующим
образом:
-
В обеих таблицах в поле
Host
можно использовать шаблонные символы `%' и `_'. -
В обеих таблицах
'%'
или пустое значение в полеHost
означает ``любой хост''. В обеих таблицах в поляхDb
,Table_name
иColumn_name
запрещено использовать шаблонные символы или пустое значение.
Таблицы_priv
и columns_priv
сортируются по полям Host
, Db
и User
. Эта
сортировка проводится так же, как и в таблице db
, хотя в данном случае
задача несколько упрощается, т.к. шаблонные символы могут встретиться
только в поле Host
.
Ниже описывается процесс верификации запроса. (Если вы хорошо знакомы с исходным кодом проверки доступа, то заметите некоторые отличия: приведенное здесь описание несколько упрощено, чтобы сделать его более понятным, однако оно соответствует тому, что в действительности делает код).
Для запросов на администрирование (SHUTDOWN
, RELOAD
, etc.) сервер
проверяет запись только в таблице user
, т.к. это единственная таблица,
которая определяет привилегии администрирования. Доступ предоставляется
при условии, что выбранная запись разрешает затребованные операции, и
запрещается в противном случае. Например, вы хотите завершить работу mysql
с помощью mysqladmin shutdown
, но ваша запись в таблице user
не
предоставляет вам привилегию SHUTDOWN
. В этом случае в доступе будет
отказано без дальнейшей проверки таблицы db
и host
(поскольку в них
отсутствует столбец Shutdown_priv
, в такой проверке нет необходимости).
В случае запросов, относящихся к базам данных (INSERT
, UPDATE
и т.д.),
сервер сначала проверяет глобальные привилегии пользователя (привилегии
суперпользователя), просматривая запись в таблице user
. Если эта запись
разрешает затребованную операцию, доступ предоставляется. Если глобальные
привилегии, указанные в таблице user
, недостаточны, сервер проверяет
таблицы db
и host
и определяет привилегии пользователя на уровне баз
данных:
-
Сервер просматривает таблицу
db
в поисках записи с подходящими значениями в поляхHost
,Db
иUser
. ПоляHost
иUser
сравниваются с именем подключающегося хоста и именем пользователя MySQL. ПолеDb
сравнивается с именем базы данных, к которой пользователь хочет получить доступ. Если запись с подходящими значениями в поляхHost
иUser
отсутствует, в доступе будет отказано. -
Если же в таблице
db
имеется подходящая запись и значение в полеHost
- не пустое, эта запись определяет привилегии пользователя, касающиеся базы данных. -
Если же в подходящей записи, выбранной в таблице
db
, значение в поле Host пустое, это означает, что перечень хостов, которым разрешен доступ к требуемой базе данных, приведен в таблицеhost
. В этом случае дальнейший поиск производится в таблицеhost
, где ищется запись с подходящими значениями в поляхHost
иDb
. Если ни одной подходящей записи в таблицеhost
нет, в доступе будет отказано. Если такая запись имеется, привилегии пользователя на уровне базы данных вычисляются путем логического умножения (не логического сложения!) привилегий, найденных в записях, которые выбраны в таблицахdb
иhost
. Другими словами, пользователю назначаются те привилегии, для которых в обеих записях установлено значение'Y'
. (Этот способ можно использовать следующим образом: предоставить всеобщие привилегии в записи, хранящейся в таблицеdb
, а затем выборочно ограничить их отдельно по каждому хосту, используя для этого записи в таблицеhost
.)
Определив привилегии на уровне базы данных, предоставляемые записями в
таблицах db
и host
, сервер добавляет их к глобальным привилегиям, заданным
в таблице user
. Если в результате привилегий оказывается достаточно для
выполнения затребованной операции, доступ предоставляется. В противном
случае сервер проверяет по таблицам tables_priv
и columns_priv
привилегии
пользователя на уровне таблиц и столбцов и добавляет их к уже имеющимся
привилегиям. В зависимости от полученного результата доступ либо
предоставляется, либо нет.
Если приведенное выше описание вычислений привилегий пользователя перевести на язык алгебры логики, используя логические операторы, то в результате получится примерно следующее:
global privileges OR (database privileges AND host privileges) OR table privileges OR column privileges
Сам по себе алгоритм определения привилегий на первый взгляд может
показаться неочевидным. И в самом деле, если первоначально глобальных
привилегий, определяемых таблицей user
, оказывается недостаточно для
выполнения затребованной операции, то зачем впоследствии эти вроде бы
бесполезные привилегии добавляются к привилегиям на уровне баз данных,
таблиц и столбцов? Смысл такого добавления заключается в том, что для
выполнения запроса может потребоваться не один, а несколько типов
привилегий. Например, для выполнения оператора INSERT ... SELECT
вам
потребуется как привилегия INSERT
, так и привилегия SELECT
. Ваши
привилегии могут быть таковы, что запись в таблице user предоставляет вам
одну привилегию, а запись в таблице db
- другую. Другими словами,
привилегии, необходимые для выполнения запроса, у вас есть, но сервер не
может выяснить при просмотре каждой таблицы в отдельности, и поэтому
привилегии, предоставляемые записями из обеих таблиц, должны быть
объединены.
Таблицу host
можно использовать еще для одной цели - для поддержки списка
надежных серверов.
В таблицах на TcX host
содержит список всех машин локальной сети. Им
предоставляются все привилегии.
Таблицу host
можно также использовать для регистрации хостов, которые
являются ненадежными. Предположим, одна из ваших машин -
public.your.domain
находится в общедоступной области, которую вы считаете
незащищенной. В таком случае можно разрешить доступ всем хостам вашей
сети, за исключением одной ``неблагонадежной'' машины, используя записи в
таблице host
, подобные приведенным ниже:
+--------------------+----+- | Host | Db | ... +--------------------+----+- | public.your.domain | % | ... (для всех привилегий установлено значение 'N') | %.your.domain | % | ... (для всех привилегий установлено значение 'Y') +--------------------+----+-
Естественно, всегда нужно протестировать записи в таблицах привилегий
(например, с помощью mysqlaccess
), чтобы убедиться в том, что привилегии
доступа установлены вами действительно так, как задумано.
4.2.11 Причины появления ошибок Access denied
("в доступе отказано")
Если при попытке подсоединения к серверу MySQL вы сталкиваетесь с ошибкой
Access denied
, то воспользуйтесь приведенным ниже списком. В нем
перечислены меры, которые можно принять для решения этой проблемы:
-
Запускали ли вы после инсталляции MySQL скрипт
mysql_install_db
для установки начального содержимого таблиц привилегий? Если нет, сделайте это. Обратитесь к разделу See section 4.3.4 Задание изначальных привилегий MySQL. Проверьте первоначальные привилегии с помощью следующей команды:shell> mysql -u root test
Подсоединение должно произойти без сбоя. Следует также убедиться, что в каталоге базы данных MySQL имеется файл `user.MYD'. Обычно он находится в директории `PATH/var/mysql/user.MYD', гдеPATH
- путь к корневому каталогу инсталляции MySQL. -
После новой инсталляции следует подсоединиться к серверу и создать
пользователей, а также установить для них права доступа:
shell> mysql -u root mysql
Сервер разрешит подсоединение, т.к. пользователь MySQL с именем пользователяroot
исходно не имеет пароля. Но в этом заключается также и риск нарушения безопасности системы, поэтому при создании остальных пользователей MySQL, вам, помимо прочего, следует задать пароль для пользователяroot
. Если при попытке подсоединения от имени пользователя root вы получите следующую ошибку:Access denied for user: '@unknown' to database mysql
это означает, что в таблицеuser
отсутствует запись со значением'root'
в столбцеUser
иmysqld
не может определить имя хоста для вашего клиента. В этом случае необходимо перезапустить сервер с опцией--skip-grant-tables
и отредактировать файл `/etc/hosts' или `\windows\hosts', добавив в него запись для вашего хоста. -
Если вы столкнетесь с такой ошибкой, как:
shell> mysqladmin -u root -pxxxx ver Access denied for user: 'root@localhost' (Using password: YES)
это означает, что используется неверный пароль. Обратитесь к разделу See section 4.3.7 Задание паролей. Если вы забыли пароль для пользователяroot
, то перезапуститеmysqld
с опцией--skip-grant-tables
и измените пароль. Обратитесь к разделу See section A.4.2 Как переустановить забытый пароль пользователяroot
. Такая ошибка может появляться даже в том случае, если вы не задавали пароля вообще - это значит, что в каком-то файле `my.ini' имеется неверный пароль. Обратитесь к разделу See section 4.1.2 Файлы параметров `my.cnf'. Отменить использование файлов опций можно с помощью опции the--no-defaults
, как показано ниже:shell> mysqladmin --no-defaults -u root ver
-
Запускали ли вы скрипт
mysql_fix_privilege_tables
при обновлении имеющейся инсталляции MySQL, если установленная версия - более ранняя, чем 3.22.11, а обновляется она до 3.22.11 или более поздней? Если нет, сделайте это. Начиная с MySQL 3.22.11, когда операторGRANT
стал функциональным, структура таблиц привилегий изменилась. - Если во время сеанса ваши привилегии изменились, то, возможно, их изменил суперпользователь. Перезагрузка таблиц привилегий отражается не только на новых подсоединениях клиентов, но также на уже имеющихся, как это показано в разделе See section 4.3.3 Когда изменения в привилегиях вступают в силу.
-
Если не удается добиться, чтобы пароль работал, помните, что функция
PASSWORD()
должна использоваться, если вы задаете пароль с помощью операторовINSERT
,UPDATE
илиSET PASSWORD
. Если же вы задаете пароль с помощью оператораGRANT ... INDENTIFIED BY
или командыmysqladmin password
, функцияPASSWORD()
не нужна. Обратитесь к разделу See section 4.3.7 Задание паролей. -
localhost
- это синоним имени вашего локального хоста, и, если хост явно не задан, также устанавливаемое по умолчанию имя хоста, к которому клиенты пытаются подключиться. Однако подсоединения кlocalhost
не действуют, если в вашей рабочей системе используются MIT-потоки и MySQL старше версии 3.23.27 (подсоединения кlocalhost
осуществляются с использованием сокетов Unix, а они не поддерживались тогда технологией MIT-потоков). Чтобы в таких системах эта проблема не возникала, следует явным образом задать имя серверного хоста с помощью опции--host
. Таким образом будет установлено подсоединение к серверуmysqld
по протоколу TCP/IP. В этом случае в записях таблицыuser
, хранящейся на серверном хосте, должно быть указано реальное имя хоста. (Это справедливо даже для тех случаев, когда клиентская программа и сервер запускаются на одном хосте). -
Если при попытке подсоединения к базе данных с помощью команды
mysql -u user_name db_name
возникает ошибкаAccess denied
, причина этого, возможно, кроется в таблицеuser
. Чтобы проверить это, выполните командуmysql -u root mysql
и введите следующий SQL-оператор:mysql> SELECT * FROM user;
В результате будет выведена запись со столбцамиHost
иUser
, соответствующими имени вашего компьютера и вашему имени пользователя MySQL. -
Сообщение об ошибке
Access denied
информирует вас о том, под каким именем вы пытаетесь войти в систему, об имени хоста, с которого вы пытаетесь установить соединение, и о том, использовали ли вы при этом пароль или нет. Как правило, в таблицеuser
будет одна запись, точно соответствующая имени хоста и имени пользователя, указанным в сообщении об ошибке. Например, если вы получите сообщение об ошибке, в котором сказаноUsing password: NO
, это означает, что вы пытались войти в систему, не указав пароль. -
Если при попытке подсоединения не с того компьютера, на котором
работает сервер MySQL, а с другого, вы получите сообщение об ошибке,
приведенное ниже, то в таблице
user
отсутствует строка с таким именем хоста:Host ... is not allowed to connect to this MySQL server
Чтобы исправить эту ошибку, с помощью утилиты командной строкиmysql
(на серверном хосте!) добавьте строку в таблицуuser
,db
илиhost
с комбинацией имени пользователя/хоста, соответствующей той, которую вы используете при попытке подсоединения. Затем выполните командуmysqladmin flush-privileges
. Если вы используете MySQL версии, отличной от Version 3.22, и вам неизвестно имя хоста или IP-адрес компьютера, с которого вы подсоединяетесь, введите в таблицу user запись со значением'%'
в полеHost
и перезапуститеmysqld
на серверной машине с опцией--log
. Когда соединение с клиентской машины будет установлено, вы найдете в журнале регистрации MySQL информацию об имени хоста, с которого вы подсоединились. (После этого следует заменить в записи таблицыuser
значение'%'
настоящим именем хоста, из журнала регистрации. Иначе ваша система останется незащищенной.) В Linux причиной такой ошибки может быть то, что бинарная версия MySQL скомпилирована с версией glibc, отличной от используемой вами. В этом случае нужно будет либо обновить ОС/glibc, используемые вами, либо загрузить исходный код MySQL и скомпилировать сервер самостоятельно. Как правило, исходный RPM компилируется и инсталлируется элементарно, так что это не составит серьезной проблемы. -
Если будет выдано сообщение об ошибке, в котором имя хоста не указано
вообще или указан IP-адрес, хотя вы при попытке подсоединения
указывали имя хоста:
shell> mysqladmin -u root -pxxxx -h some-hostname ver Access denied for user: 'root' (Using password: YES)
то это означает, что ошибка возникает при попытке MySQL сопоставить IP-адрес с именем хоста. В этом случае вы можете выполнить командуmysqladmin flush-hosts
, чтобы сбросить внутреннюю кэш-память DNS. Обратитесь к разделу See section 5.5.5 Как MySQL использует DNS. Вот некоторые способы решения этой проблемы:- Попробуйте выяснить, что не так с вашим сервером DNS, и устраните неисправность.
- Задайте IP-адреса вместо имен хостов таблицах привилегий MySQL.
- Запустите
mysqld
с опцией--skip-name-resolve
. - Запустите
mysqld
с опцией--skip-host-cache
. - Подключитесь к
localhost
если ваш сервер и клиент работают на одном и том же компьютере. - Поместите имена клиентских машин в каталог `/etc/hosts'.
-
Если команда
mysql -u root test
работает успешно, а командаmysql -h your_hostname -u root tes
t приводит к ошибкеAccess denied
, то, возможно, в таблицеuser
имя вашего хоста указано неверно. Одна из распространенных проблем здесь заключается в том, что в полеHost
записи, хранящейся в таблицеuser
, задается только имя хоста, в то время как процедуры разрешения имен, используемые вашей системой, возвращают полностью определенное доменное имя (или наоборот). Например, если в таблице user имеется запись со значением'tcx'
в полеhost
, а DNS при этом сообщает MySQL, что имя хоста -'tcx.subnet.se'
, эта запись действовать не будет. Попробуйте добавить в таблицуuser
запись, указав в колонкеHost
IP-адрес хоста. (В качестве альтернативы можно добавить в таблицуuser
запись со значением в полеHost
, содержащим шаблонный символ, например'tcx.%'
. Но использовать имена хостов, оканчивающиеся на'%'
- небезопасно и делать это не рекомендуется!) -
Если команда
mysql -u user_name test
работает успешно, а командаmysql -u user_name other_db_nam
e - нет, то в таблицеdb
нет записи, соответствующейother_db_name
. -
Если команда
mysql -u user_name db_name
выполняется успешно на том компьютере, где установлен сервер, аmysql -u host_name -u user_name db_name
не работает при выполнении ее на другой клиентской машине, то в таблицахuser
илиdb
эта клиентская машина не зарегистрирована. -
Если не удается выяснить причину ошибки
Access denied
, удалите из таблицыuser
все записи, в которых значение в полеHost
включает шаблонные символы (записи, содержащие символы `'%'' или `'_''). Очень распространенной ошибкой является следующая: пользователь вставляет новую запись со значением'%'
в полеHost
и со значением'some user'
- в полеUser
, полагая, что после этого для подсоединения с той же самой машины он сможет использоватьlocalhost
. Такой расчет неверен, и причина здесь в том, что устанавливаемые по умолчанию привилегии включают запись со значением'localhost'
в полеHost
и пустым полемUser
. И поскольку в этой записи значение'localhost'
более конкретно, чем'%',
то именно она при подсоединении сlocalhost
предшествует новой записи и, соответственно, будет выбрана и сработает! Правильным в этом случае будет вставить вторую запись со значением'localhost'
в полеHost
и значением'some_user'
- в полеUser
или удалить запись со значением'localhost'
в полеHost
и пустым полемUser
. -
Если вы получите следующую ошибку, то эта проблема, возможно, связана
с таблицей
db
или таблицейhost
:Access to database denied
Если в записи, выбранной из таблицыdb
, столбецHost
- пустой, удостоверьтесь, что в таблицеhost
имеется по крайней мере одна соответствующая запись, указывающая, к каким хостам относится запись из таблицыdb
. Если ошибка возникает при выполнении SQL-командыSELECT ... INTO OUTFILE
илиLOAD DATA INFILE
, то в вашей записи из таблицыuser
, вероятно, отсутствует разрешение на предоставление привилегииFILE
. -
Помните, что клиентские программы будут использовать параметры
подсоединения, указанные файлах конфигурации или переменных окружения.
Обратитесь к разделу See section E Переменные окружения. Если есть подозрение, что
клиент отсылает неверные устанавливаемые по умолчанию параметры
подсоединения, в случае, когда вы не задаете их в командной строке,
проверьте ваше окружение и файл `my.cnf' в своей домашней директории.
Можете также проверить конфигурационные файлы MySQL относящиеся ко все
системе, хотя параметры клиентского подсоединения вряд ли указаны
именно здесь. Обратитесь к разделу See section 4.1.2 Файлы параметров `my.cnf'. Если ошибка
Access denied
возникает при выполнении вашей клиентской программы без каких-либо опций, убедитесь, что ни в одном из ваших файлов опций не указан старый пароль! Обратитесь к разделу See section 4.1.2 Файлы параметров `my.cnf'. -
Если вы вносите изменения в таблицы привилегий непосредственно (с
помощью операторов
INSERT
илиUPDATE
), а ваши изменения, похоже, игнорируются, то следует выдать операторFLUSH PRIVILEGES
или выполнить командуmysqladmin flush-privileges
- для того, чтобы заставить сервер перечитать таблицы привилегий. В противном случае ваши изменения вступят в силу лишь при последующем перезапуске сервера. Помните, что после того, как вы зададите пароль от имени пользователя, вам нужно будет указывать его только после сброса привилегий, т.к. серверу еще не будет известно о том, что вы изменили пароль! -
При возникновении проблемы с доступом при использовании Perl-, PHP-,
Python- или ODBC-программ, попробуйте установить соединение с сервером
при помощи команды
mysql -u user_name db_name
или командыmysql -u user_name -pyour_pass db_name
. Если ваш клиентmysql
обеспечивает подсоединение, то проблема связана не с привилегиями доступа, а с вашей программой. (Заметим, что между-p
и паролем пробела нет; для задания пароля можно также использовать синтаксическую структуру--password=your_pass
. Если вы используете только саму опцию-p
, MySQL запросит у вас пароль) -
При тестировании запускайте демон
mysqld
с опцией--skip-grant-tables
. Тогда вы сможете изменять таблицы привилегий MySQL и с помощью скриптаmysqlaccess
проверять, произвели ли сделанные вами изменения желаемый эффект. Если результаты вас устраивают, выполните командуmysqladmin flush-privileges
, чтобы приказать серверуmysqld
приступить к использованию новых таблиц привилегий. Внимание: перезагрузка таблиц привилегий отменяет опцию--skip-grant-tables
. Это позволяет заставить сервер приступить к использованию новых таблиц привилегий без завершения его работы и перезагрузки. -
Если ничего не помогает, запустите демон
mysqld
daemon с опцией отладки (например--debug=d,general,query
). В результате будет выведена информация о неудачных подсоединениях, с указанием хоста и пользователя, а также обо всех обработанных командах. Обратитесь к разделу See section D.1.2 Создание трассировочных файлов. -
Если у вас имеется какая-либо проблема с таблицами привилегий MySQL и
вы полагаете, что необходимо сообщить о ней в список рассылки, нужно
обязательно приложить к своему отчету распечатку таблиц привилегий
MySQL. Это можно сделать с помощью команды
mysqldump mysql
. Отчет о проблеме, как и в других случаях, отправляется с помощью скриптаmysqlbug
. Обратитесь к разделу See section 1.8.1.3 Как отправлять отчеты об ошибках или проблемах. В некоторых случаях для выполнения скриптаmysqldump
возможно, потребуется перезапуститьmysqld
с опцией--skip-grant-tables
.
4.3 Управление учетными записями пользователей MySQL
4.3.1 Синтаксис команд GRANT
и REVOKE
GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...] ON {tbl_name | * | *.* | db_name.*} TO user_name [IDENTIFIED BY [PASSWORD] 'password'] [, user_name [IDENTIFIED BY 'password'] ...] [REQUIRE NONE | [{SSL| X509}] [CIPHER cipher [AND]] [ISSUER issuer [AND]] [SUBJECT subject]] [WITH [GRANT OPTION | MAX_QUERIES_PER_HOUR # | MAX_UPDATES_PER_HOUR # | MAX_CONNECTIONS_PER_HOUR #]] REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...] ON {tbl_name | * | *.* | db_name.*} FROM user_name [, user_name ...]
GRANT
включен в MySQL начиная с версии 3.22.11 и выше. В более ранних
версиях MySQL оператор GRANT
ничего не выполняет.
Команды GRANT
и REVOKE
позволяют системным администраторам создавать
пользователей MySQL, а также предоставлять права пользователям или лишать
их прав на четырех уровнях привилегий:
- Глобальный уровень
-
Глобальные привилегии применяются ко всем базам данных на указанном
сервере. Эти привилегии хранятся в таблице
mysql.user
. - Уровень базы данных
-
Привилегии базы данных применяются ко всем таблицам указанной базы данных.
Эти привилегии хранятся в таблицах
mysql.db
иmysql.host
. - Уровень таблицы
-
Привилегии таблицы применяются ко всем столбцам указанной таблицы. Эти
привилегии хранятся в таблице
mysql.tables_priv
. - Уровень столбца
-
Привилегии столбца применяются к отдельным столбцам указанной таблицы. Эти
привилегии хранятся в таблице
mysql.columns_priv
.
Если привилегии предоставляются пользователю, которого не существует, то
этот пользователь создается. Чтобы просмотреть примеры работы команды
GRANT
, см. раздел section 4.3.5 Добавление новых пользователей в MySQL.
В таблице приведен список возможных значений параметра priv_type
для
операторов GRANT
и REVOKE
:
ALL [PRIVILEGES] | Задает все простые привилегии, кроме WITH GRANT OPTION
|
ALTER | Разрешает использование ALTER TABLE
|
CREATE | Разрешает использование CREATE TABLE
|
CREATE TEMPORARY TABLES | Разрешает использование CREATE TEMPORARY TABLE
|
DELETE | Разрешает использование DELETE
|
DROP | Разрешает использование DROP TABLE
|
EXECUTE | Разрешает пользователю запускать хранимые процедуры (для MySQL 5.0) |
FILE | Разрешает использование SELECT ... INTO OUTFILE и LOAD DATA INFILE
|
INDEX | Разрешает использование CREATE INDEX and DROP INDEX
|
INSERT | Разрешает использование INSERT
|
LOCK TABLES | Разрешает использование LOCK TABLES на таблицах, для которых есть привилегия SELECT
|
PROCESS | Разрешает использование SHOW FULL PROCESSLIST
|
REFERENCES | Зарезервировано для использования в будущем |
RELOAD | Разрешает использование FLUSH
|
REPLICATION CLIENT | Предоставляет пользователю право запрашивать местонахождение головного и подчиненных серверов |
REPLICATION SLAVE | Необходимо для подчиненных серверов при репликации (для чтения информации из бинарных журналов головного сервера) |
SELECT | Разрешает использование SELECT
|
SHOW DATABASES | SHOW DATABASES выводит все базы данных
|
SHUTDOWN | Разрешает использование mysqladmin shutdown
|
SUPER | Позволяет установить одно соединение (один раз), даже если достигнуто значение max_connections, и запускать команды CHANGE MASTER , KILL thread , mysqladmin debug , PURGE MASTER LOGS и SET GLOBAL
|
UPDATE | Разрешает использование UPDATE
|
USAGE | Синоним для ``без привилегий'' |
GRANT OPTION | Синоним для WITH GRANT OPTION
|
Значение USAGE
можно задавать, если необходимо создать пользователя без
привилегий.
Привилегии CREATE TEMPORARY TABLES
, EXECUTE
, LOCK TABLES
, REPLICATION ...
,
SHOW DATABASES
и SUPER
являются новыми для версии 4.0.2. Чтобы
воспользоваться этими новыми привилегиями после обновления до версии
4.0.2, необходимо запустить скрипт mysql_fix_privilege_tables
.
В боле старых версиях MySQL привилегия PROCESS
предоставляет такие же
права, как и новая привилегия SUPER
.
Чтобы лишить пользователя привилегий, предоставленных командой GRANT
,
воспользуйтесь значением priv_type
в GRANT OPTION
:
mysql> REVOKE GRANT OPTION ON ... FROM ...;
Для таблицы можно указать только следующие значения priv_type
:
SELECT
, INSERT
, UPDATE
, DELETE
, CREATE
,
DROP
, GRANT OPTION
, INDEX
и ALTER
.
Для столбца можно указать только следующие значения priv_type
(при
использовании оператора column_list
): SELECT
, INSERT
и UPDATE
.
Глобальные привилегии можно задать, воспользовавшись синтаксисом ON *.*
, а
привилегии базы данных - при помощи синтаксиса ON db_name.*
. Если указать
ON *
при открытой текущей базе данных, то привилегии будут заданы для этой
базы данных. (Предупреждение: если указать ON *
при отсутствии открытой
текущей базы данных, это повлияет на глобальные привилегии!)
Заметьте: шаблонные символы `_' и `%' не допускаются в определении
имени баз данных в операторе GRANT. Это означает, что если вы хотите
использовать, скажем, символ `_' в имени базы данных, то вы должны указать
его как `\_' в GRANT
, чтобы пользователь не имел возможности
получить доступ к другим базам данных, соответствующих шаблону: GRANT ...
ON `foo\_bar`.* TO ...
.
С тем, чтобы можно было определять права пользователям с конкретных
компьютеров, в MySQL обеспечивается возможность указывать имя пользователя
(user_name
) в форме user@host
. Если необходимо указать строку user
, в
которой содержатся специальные символы (такие как `-') или строку host
, в
которой содержатся специальные или групповые символы (такие как `%'),
можно заключить имя удаленного компьютера или пользователя в кавычки
(например, 'test-user'@'test-hostname'
).
В имени удаленного компьютера также можно указывать групповые символы.
Например, user@'%.loc.gov'
относится к user
всех удаленных компьютеров
домена loc.gov
, а user@'144.155.166.%'
относится к user
всех удаленных
компьютеров подсети 144.155.166
класс C.
Простая форма user является синонимом для user@"%"
.
В MySQL не поддерживаются групповые символы в именах пользователей.
Анонимные пользователи определяются вставкой записей User=''
в таблицу
mysql.user
или созданием пользователя с пустым именем при помощи команды
GRANT
.
Примечание: если анонимным пользователям разрешается подсоединяться к
серверу MySQL, необходимо также предоставить привилегии всем локальным
пользователям как user@localhost
, поскольку в противном случае при попытке
пользователя зайти в MySQL с локального компьютера в таблице mysql.user
будет использоваться вход для анонимного пользователя!
Чтобы проверить, происходит ли подобное на вашем компьютере, выполните следующий запрос:
mysql> SELECT Host,User FROM mysql.user WHERE User='';
На данный момент команда GRANT
поддерживает имена удаленных компьютеров,
таблиц, баз данных и столбцов длиной не более 60 символов. Имя
пользователя должно содержать не более 16 символов.
Привилегии для таблицы или столбца формируются при помощи логического
оператора OR из привилегий каждого из четырех уровней. Например, если в
таблице mysql.user
указано, что у пользователя есть глобальная привилегия
SELECT
, эта привилегия не отменяется на уровне базы данных, таблицы или
столбца.
Привилегии для столбца могут быть вычислены следующим образом:
глобальные привилегии OR (привилегии базы данных AND привилегии удаленного компьютера) OR привилегии таблицы OR привилегии столбца
В большинстве случаев права пользователя определяются только на одном уровне привилегий, поэтому обычно эта процедура не настолько сложна, как описано выше. Подробная информация о последовательности действий проверки привилегий представлена в разделе section 4.2 Общие проблемы безопасности и система привилегий доступа MySQL.
Если привилегии предоставляются сочетанию пользователь/удаленный
компьютер, которое отсутствует в таблице mysql.user
, то в последнюю
добавляется запись, которая остается в таблице до тех пор, пока не будет
удалена при помощи команды DELETE
. Иначе говоря, команда GRANT
может
создавать записи user
в таблице, но команда REVOKE
не может их удалить.
Это необходимо делать при помощи команды DELETE
.
Если в MySQL версий 3.22.12 и выше создан новый пользователь или
предоставлены глобальные привилегии, пароль пользователя будет назначаться
оператором IDENTIFIED BY
, если он указан. Если у пользователя уже есть
пароль, то этот пароль будет заменен новым.
Если вы не хотите отправлять пароль открытым текстом, можно
воспользоваться параметром PASSWORD
с зашифрованным паролем, полученным
при помощи функции SQL PASSWORD()
или функции C API
make_scrambled_password(char *to, const char *password)
.
Предупреждение: если при создании нового пользователя не указать оператор
IDENTIFIED BY
, будет создан пользователь без пароля. Это ненадежно с точки
зрения безопасности.
Пароли также можно задавать при помощи команды SET PASSWORD
. See section 6.2.3.4 Тип множества SET
.
Если у вас привилегии для базы данных, то при необходимости в таблице
mysql.db
создается запись. Данная запись удаляется после удаления всех
привилегий для этой базы данных командой REVOKE
.
Если у пользователя нет никаких привилегий для таблицы, то таблица не
отображается, когда пользователь запрашивает список таблиц (например, при
помощи оператора SHOW TABLES
).
Оператор WITH GRANT OPTION
предоставляет пользователю возможность наделять
других пользователей любыми привилегиями, которые он сам имеет на
указанном уровне привилегий. При предоставлении привилегии GRANT
необходимо проявлять осмотрительность, так как два пользователя с разными
привилегиями могут объединить свои привилегии!
Параметры MAX_QUERIES_PER_HOUR #
, MAX_UPDATES_PER_HOUR #
и
MAX_CONNECTIONS_PER_HOUR #
являются новыми в MySQL версии 4.0.2. Эти
параметры ограничивают количество запросов, обновлений и входов, которые
пользователь может осуществить в течение одного часа. Если установлено
значение 0 (принято по умолчанию), то это означает, что для данного
пользователя нет ограничений. See section 4.3.6 Ограничение ресурсов пользователя.
Внимание: чтобы указать любую из этих опция для существующего пользователя, но не
давать никаких дополнительных привилегий, используйте GRANT USAGE ... WITH MAX_...
.
Нельзя предоставить другому пользователю привилегию, которой нет у вас
самого. Привилегия GRANT
позволяет предоставлять только те привилегии,
которыми вы обладаете.
Учтите, что если пользователю назначена привилегия GRANT
на определенном
уровне привилегий, то все привилегии, которыми этот пользователь уже
обладает (или которые будут ему назначены в будущем!) на этом уровне,
также могут назначаться этим пользователем. Предположим, пользователю
назначена привилегия INSERT
в базе данных. Если потом в базе данных
назначить привилегию SELECT
и указать WITH GRANT OPTION
, пользователь
сможет назначать не только привилегию SELECT
, но также и INSERT
. Если
затем в базе данных предоставить пользователю привилегию UPDATE
,
пользователь сможет после этого назначать INSERT
, SELECT
и UPDATE
.
Не следует назначать привилегии ALTER
обычным пользователям. Это дает
пользователю возможность разрушить систему привилегий путем переименования
таблиц!
Обратите внимание на то, что если используются привилегии для таблицы или столбца даже для одного пользователя, сервер проверяет привилегии таблиц и столбцов для всех пользователей, и это несколько замедляет работу MySQL.
При запуске mysqld
все привилегии считываются в память. Привилегии базы
данных, таблицы и столбца вступают в силу немедленно, а привилегии уровня
пользователя - при следующем подсоединении пользователя. Изменения в
таблицах назначения привилегий, которые осуществляются при помощи команд
GRANT
и REVOKE
, обрабатываются сервером немедленно. Если изменять таблицы
назначения привилегий вручную (используя команды INSERT
, UPDATE
и т.д.),
необходимо запустить оператор FLUSH PRIVILEGES
или mysqladmin
flush-privileges
, чтобы указать серверу на необходимость перезагрузки
таблиц назначения привилегий. See section 4.3.3 Когда изменения в привилегиях вступают в силу.
Наиболее значительные отличия команды GRANT
версий ANSI SQL и MySQL
следующие:
- В MySQL привилегии назначаются для сочетания имя пользователя + удаленный компьютер, а не только для имени пользователя.
-
В ANSI SQL отсутствуют глобальные привилегии и привилегии уровня базы
данных, и ANSI SQL поддерживает не все типы привилегий MySQL. В свою
очередь, в MySQL отсутствует поддержка привилегий ANSI SQL
TRIGGER
,UNDER
. - Структура привилегий ANSI SQL является иерархической. Если удалить пользователя, то все назначенные этому пользователелю привилегии будут отменены. В MySQL назначенные привилегии не отменяются автоматически, их при необходимости требуется удалять самостоятельно.
-
В MySQL пользователь может применять к таблице оператор
INSERT
при наличии у него привилегииINSERT
только для нескольких столбцов в этой таблице. Столбцы, для которых отсутствует привилегияINSERT
, будут установлены в свои значения, принятые по умолчанию. В ANSI SQL требуется наличие привилегииINSERT
для всех столбцов. -
При удалении таблицы в ANSI SQL все привилегии для этой таблицы будут
отменены. Если отменить привилегию в ANSI SQL, то все привилегии,
которые были назначены на основе этой привилегии, также будут
отменены. В MySQL привилегии могут удаляться только при помощи команды
REVOKE
или путем изменения таблиц назначения привилегий MySQL.
Чтобы ознакомиться с описанием использования REQUIRE
, см. раздел See section 4.3.9 Использование безопасных соединений.
4.3.2 Имена пользователей MySQL и пароли
Между MySQL и Unix или Windows существует несколько различий в использовании имен пользователей и паролей:
-
Имена пользователей, которые применяются в MySQL для авторизации, не
имеют ничего общего с именами пользователей Unix (аккаунты Unix) или
именами пользователей Windows. Большинство клиентов MySQL по умолчанию
пытаются войти в систему, используя текущее имя пользователя Unix в
качестве имени пользователя MySQL, но это сделано только для удобства.
Программы клиентов позволяют указывать различные имена при помощи
параметров
-u
или--user
. Это означает, что невозможно обеспечить безопасность базы данных, если не все имена пользователей MySQL снабжены паролями: ведь можно попытаться подсоединиться к серверу, используя любое имя, а если воспользоваться именем, которому не назначен пароль, то удастся войти в систему. - Имена пользователей MySQL могут содержать до 16 символов. Имена пользователей Unix обычно ограничены 8 символами.
- Пароли MySQL не имеют никакого отношения к паролям Unix. Не существует связи между паролем, который используется для входа в Unix, и паролем, необходимым для доступа к базе данных.
-
MySQL шифрует пароли при помощи своего алгоритма, который отличается
от алгоритма Unix, используемого во время входа в систему. Описание
функций
PASSWORD()
иENCRYPT()
можно найти в разделе See section 6.3.6.2 Разные функции. Обратите внимание: даже если ваш пароль хранится в 'зашифрованном виде', то знания этого 'зашифрованного' пароля будет достаточно, чтобы подсоединиться к серверу MySQL!
Пользователи MySQL и их привилегии обычно создаются при помощи команды
GRANT
. See section 4.3.1 Синтаксис команд GRANT
и REVOKE
.
Если подсоединение к серверу MySQL осуществляется с клиента командной
строки, необходимо указать пароль при помощи параметра
--password=your-password
. See section 4.2.8 Соединение с сервером MySQL.
mysql --user=monty --password=guess database_name
Если необходимо, чтобы клиент запрашивал пароль, то следует указать
--password
без каких-либо аргументов
mysql --user=monty --password database_name
или сокращенный вариант этого параметра:
mysql -u monty -p database_name
Обратите внимание на то, что в последнем примере database_name
не является
паролем.
Если необходимо указать пароль при помощи параметра -p
, то следует
поступить следующим образом:
mysql -u monty -pguess database_name
В некоторых системах вызов библиотеки, который MySQL использует для запроса пароля, автоматически обрезает пароль до 8 символов. В самом MySQL не существует никаких ограничений на длину пароля.
4.3.3 Когда изменения в привилегиях вступают в силу
При запуске mysqld
все таблицы назначения привилегий загружаются в память
и с этого момента привилегии вступают в силу.
Изменения, которые вносятся в таблицы назначения привилегий при помощи
команд GRANT
, REVOKE
или SET PASSWORD
, учитываются сервером немедленно.
Если вносить изменения в таблицы назначения привилегий вручную (при помощи
команд INSERT
, UPDATE
и т.д.), необходимо запускать оператор FLUSH
PRIVILEGES
, mysqladmin flush-privileges
или mysqladmin reload
, чтобы
указать серверу на необходимость перезагрузить эти таблицы. В противном
случае изменения не вступят в силу, пока сервер не будет перезагружен.
Если внести изменения вручную, но не перезагрузить таблицы назначения
привилегий, то останется только удивляться, почему внесенные изменения не
действуют!
Когда сервер замечает, что были внесены изменения в таблицы назначения привилегий, он обрабатывает установленные соединения клиентов следующим образом:
- Изменения привилегий таблиц и столбцов вступают в силу при следующем запросе клиента
-
Изменения привилегий баз данных вступают в силу при следующем
использовании команды
USE db_name
- Изменения глобальных привилегий и изменения пароля вступают в силу при следующем подсоединении пользователя.
4.3.4 Задание изначальных привилегий MySQL
После установки MySQL изначальные привилегии доступа задаются при помощи
`scripts/mysql_install_db'. See section 2.3.1 Обзор быстрой установки. Скрипт mysql_install_db
запускает
сервер mysqld
, а затем инициализирует таблицы предоставления привилегий со
следующим набором привилегий:
-
В качестве суперпользователя создается MySQL
root
который может делать все, что угодно. Соединения должны устанавливаться с локального компьютера. Примечание: Изначально парольroot
пуст, поэтому кто угодно может подсоединиться в качествеroot
без пароля и получить все привилегии. -
Создается анонимный пользователь, который может выполнять любые
операции над базами данных с именами
test
или начинающимися сtest_
. Соединения должны устанавливаться с локального компьютера. Это означает, что любой локальный пользователь может подключиться без пароля и будет воспринят сервером как анонимный пользователь. -
Остальные привилегии запрещены. Например, обычный пользователь не
может использовать команды
mysqladmin shutdown
илиmysqladmin processlist
.
Примечание: В Windows принятые по умолчанию привилегии отличаются от указанных. See section 2.6.2.3 Работа MySQL в среде Windows.
Поскольку сразу после установки программа совершенно не защищена, первым
делом необходимо задать пароль для пользователя MySQL root
. Это можно
сделать следующим образом (обратите внимание, что пароль указывается при
помощи функции PASSWORD()
):
shell> mysql -u root mysql mysql> SET PASSWORD FOR root@localhost=PASSWORD('new_password');
Опытные пользователи могут работать непосредственно с таблицами назначения привилегий:
shell> mysql -u root mysql mysql> UPDATE user SET Password=PASSWORD('new_password') -> WHERE user='root'; mysql> FLUSH PRIVILEGES;
Еще один способ задать пароль - воспользоваться командой mysqladmin
:
shell> mysqladmin -u root password new_password
Изменять пароли других пользователей могут только пользователи с правом
записи/обновления базы данных mysql
. Все обычные пользователи (не
анонимные) могут модифицировать только свой собственный пароль при помощи
указанных выше команд или команды SET PASSWORD=PASSWORD('new_password')
.
Обратите внимание на то, что если пароль в таблице user
обновляется
напрямую при помощи первого метода, требуется указать серверу на
необходимость перезагрузки таблиц привилегий (при помощи команды FLUSH
PRIVILEGES
), иначе изменения не будут учтены.
После того, как был задан пароль root
, этот пароль необходимо будет
вводить, подсоединяясь к серверу как root
.
Можно оставить пароль root
пустым, тогда не придется его указывать во
время проведения дополнительных установок и тестирования. Тем не менее,
обязательно укажите его, прежде чем использовать сервер для любой реальной
работы.
Ознакомьтесь со скриптом `scripts/mysql_install_db', чтобы увидеть, как задавать привилегии по умолчанию. Данный скрипт можно использовать как основу для добавления других пользователей.
Если необходимо, чтобы изначальные привилегии отличались от указанных
выше, можно изменить базу mysql_install_db
еще до ее запуска.
Чтобы полностью заново создать таблицы предоставления привилегий, удалите
все файлы с расширениями `.frm', `.MYI' и `.MYD' в каталоге, где находится база
данных mysql
(это каталог с именем mysql
в каталоге базы данных, который
выводится на экран при запуске команды mysqld --help
). Затем запустите
скрипт mysql_install_db
(возможно, после добавления в него необходимых
привилегий).
Примечание: в более старых, чем 3.22.10, версиях MySQL файлы с расширением
`.frm' удалять не следует. Если же случайно они были удалены, их следует
восстановить, скопировав из дистрибутива MySQL до запуска
mysql_install_db
.
4.3.5 Добавление новых пользователей в MySQL
Пользователей можно добавлять двумя различными способами - при помощи
команды GRANT
или напрямую в таблицы назначения привилегий MySQL.
Предпочтительнее использовать команду GRANT
- этот способ проще и дает
меньше ошибок. See section 4.3.1 Синтаксис команд GRANT
и REVOKE
.
Существует также большое количество программ (таких как phpmyadmin
),
которые служат для создания и администрирования пользователей.
В приведенных ниже примерах демонстрируется, как использовать клиент mysql
для задания новых пользователей. В примерах предполагается, что привилегии
установлены в соответствии с принятыми по умолчанию значениями, описанными
в предыдущем разделе. Это означает, что для внесения изменений на том же
компьютере, где запущен mysqld
, необходимо подсоединиться к серверу как
пользователь MySQL root
, и у пользователя root
должна быть привилегия
INSERT
для базы данных mysql
, а также административная привилегия RELOAD
.
Кроме того, если был изменен пароль пользователя root
, его необходимо
указать здесь для команды mysql
.
Новых пользователей можно добавлять, используя команду GRANT
:
shell> mysql --user=root mysql mysql> GRANT ALL PRIVILEGES ON *.* TO monty@localhost -> IDENTIFIED BY 'some_pass' WITH GRANT OPTION; mysql> GRANT ALL PRIVILEGES ON *.* TO monty@"%" -> IDENTIFIED BY 'some_pass' WITH GRANT OPTION; mysql> GRANT RELOAD,PROCESS ON *.* TO admin@localhost; mysql> GRANT USAGE ON *.* TO dummy@localhost;
Эти команды GRANT
создают трех новых пользователей:
monty
-
Полноценный суперпользователь - он может подсоединяться к серверу откуда
угодно, но должен использовать для этого пароль
some_pass
. Обратите внимание на то, что мы должны применить операторыGRANT
как дляmonty@localhost
, так и дляmonty@"%"
. Если не добавить запись сlocalhost
, запись анонимного пользователя дляlocalhost
, которая создается при помощиmysql_install_db
, будет иметь преимущество при подсоединении с локального компьютера, так как в ней указано более определенное значение для поляHost
, и она расположена раньше в таблицеuser
. admin
-
Пользователь, который может подсоединяться с
localhost
без пароля; ему назначены административные привилегииRELOAD
иPROCESS
. Эти привилегии позволяют пользователю запускать командыmysqladmin reload
,mysqladmin refresh
иmysqladmin flush-*
, а такжеmysqladmin processlist
. Ему не назначено никаких привилегий, относящихся к базам данных (их можно назначить позже, дополнительно применив операторGRANT
). dummy
-
Пользователь, который может подсоединяться к серверу без пароля, но только
с локального компьютера. Все глобальные привилегии установлены в значение
'N'
-тип привилегииUSAGE
, который позволяет создавать пользователей без привилегий. Предполагается, что относящиеся к базам данных привилегии будут назначены позже.
Можно напрямую добавить точно такую же информацию о пользователе при
помощи оператора INSERT
, а затем дать серверу команду перезагрузить
таблицы назначения привилегий:
shell> mysql --user=root mysql mysql> INSERT INTO user VALUES('localhost','monty',PASSWORD('some_pass'), -> 'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y'); mysql> INSERT INTO user VALUES('%','monty',PASSWORD('some_pass'), -> 'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y'); mysql> INSERT INTO user SET Host='localhost',User='admin', -> Reload_priv='Y', Process_priv='Y'; mysql> INSERT INTO user (Host,User,Password) -> VALUES('localhost','dummy',''); mysql> FLUSH PRIVILEGES;
В зависимости от версии MySQL в примере, приведенном выше, может
указываться различное количество значений 'Y'
(в версиях до Version
3.22.11 было меньше столбцов привилегий). Для пользователя admin
используется более удобочитаемый расширенный синтаксис команды INSERT
,
который доступен начиная с версии 3.22.11.
Обратите внимание: чтобы создать суперпользователя, необходимо создать
запись таблицы user
с полями привилегий, установленными в значение 'Y'
.
Нет необходимости задавать значения в записях таблиц db
или host
.
Столбцы привилегий в таблице user в последнем операторе INSERT
(для
пользователя dummy
) не были заданы явно, поэтому данным столбцам был
присвоено принятое по умолчанию значение 'N'
. Точно так же действует
команда GRANT USAGE
.
В приведенном ниже примере добавляется пользователь custom
, который может
подсоединяться с компьютеров localhost
, server.domain
и whitehouse.gov
. Он
хочет получать доступ к базе данных bankaccount
только с компьютера
localhost
, к базе данных expenses
- только с whitehouse.gov
, и к базе
данных customer
- со всех трех компьютеров, а также использовать пароль
stupid
при подсоединении со всех трех компьютеров.
Чтобы задать эти привилегии пользователя при помощи оператора GRANT
,
выполните следующие команды:
shell> mysql --user=root mysql mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP -> ON bankaccount.* -> TO custom@localhost -> IDENTIFIED BY 'stupid'; mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP -> ON expenses.* -> TO custom@whitehouse.gov -> IDENTIFIED BY 'stupid'; mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP -> ON customer.* -> TO custom@'%' -> IDENTIFIED BY 'stupid';
Привилегии для пользователя custom мы назначаем потому, что этот
пользователь хочет получать доступ к MySQL как с локального компьютера
через сокеты Unix, так и с удаленного компьютера whitehouse.gov
через
протокол TCP/IP.
Чтобы задать привилегии пользователя путем непосредственного внесения
изменений в таблицы назначения привилегий, выполните следующие команды
(обратите внимание на команду FLUSH PRIVILEGES
в конце примера):
shell> mysql --user=root mysql mysql> INSERT INTO user (Host,User,Password) -> VALUES('localhost','custom',PASSWORD('stupid')); mysql> INSERT INTO user (Host,User,Password) -> VALUES('server.domain','custom',PASSWORD('stupid')); mysql> INSERT INTO user (Host,User,Password) -> VALUES('whitehouse.gov','custom',PASSWORD('stupid')); mysql> INSERT INTO db -> (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv, -> Create_priv,Drop_priv) -> VALUES -> ('localhost','bankaccount','custom','Y','Y','Y','Y','Y','Y'); mysql> INSERT INTO db -> (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv, -> Create_priv,Drop_priv) -> VALUES -> ('whitehouse.gov','expenses','custom','Y','Y','Y','Y','Y','Y'); mysql> INSERT INTO db -> (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv, -> Create_priv,Drop_priv) -> VALUES('%','customer','custom','Y','Y','Y','Y','Y','Y'); mysql> FLUSH PRIVILEGES;
Первые три оператора INSERT
добавляют в таблицу user записи, которые
позволят пользователю custom
подключаться с различных компьютеров с
указанным паролем, но не дают ему никаких привилегий (все привилегии
установлены в принятое по умолчанию значение 'N'
). Следующие три оператора
INSERT
добавляют записи в таблицу db
, в которой назначаются привилегии для
пользователя custom
по отношению к базам данных bankaccount
, expenses
и
customer, но только если доступ осуществляется с определенных компьютеров.
Как обычно, после внесения изменений непосредственно в таблицы назначения
привилегий серверу необходимо дать команду на перезагрузку этих таблиц
(при помощи FLUSH PRIVILEGES
), чтобы внесенные изменения вступили в силу.
Если необходимо предоставить определенному пользователю доступ с любого
компьютера к определенному домену, можно воспользоваться оператором GRANT
следующим образом:
mysql> GRANT ... -> ON *.* -> TO myusername@"%.mydomainname.com" -> IDENTIFIED BY 'mypassword';
Чтобы сделать то же самое путем непосредственного внесения изменений в таблицы назначения привилегий, выполните следующие действия:
mysql> INSERT INTO user VALUES ('%.mydomainname.com', 'myusername', -> PASSWORD('mypassword'),...); mysql> FLUSH PRIVILEGES;
4.3.6 Ограничение ресурсов пользователя
Начиная с MySQL версии 4.0.2 можно ограничивать определенные ресурсы, выделяемые пользователям.
До этой версии единственным возможным методом ограничения использования
ресурсов сервера MySQL была установка переменной запуска
max_user_connections
в значение, отличное от нуля. Но этот метод действует
только на глобальном уровне и не позволяет управлять отдельными
пользователями. Он может представлять определенный интерес только для
провайдеров услуг Internet.
На уровне отдельного пользователя теперь введено управление следующими тремя ресурсами:
- Количество всех запросов в час: все команды, которые может запускать пользователь.
- Количество всех обновлений в час: любая команда, которая изменяет таблицу или базу данных.
- Количество соединений, сделанных за час: новые соединения, открытые за час.
Пользователь в упомянутом выше контексте представляет собой отдельную
запись в таблице user, которая уникальным образом идентифицируется своими
столбцами user
и host
.
По умолчанию все пользователи не ограничены в использовании указанных выше
ресурсов только в случае, только если эти ограничения не наложены на них.
Данные ограничения могут быть наложены только при помощи глобальной
команды GRANT (*.*)
с использованием следующего синтаксиса:
GRANT ... WITH MAX_QUERIES_PER_HOUR N1 MAX_UPDATES_PER_HOUR N2 MAX_CONNECTIONS_PER_HOUR N3;
Можно указать любое сочетание приведенных выше ресурсов. N1, N2 и N3 являются целыми числами, представляющими собой значения количеств запросов/обновлений/соединений в час.
Если пользователь в течение часа достигает предела любого из вышеуказанных значений, его соединение будет прервано с выдачей соответствующего сообщения об ошибке.
Текущие значения для определенного пользователя могут быть сброшены
(установлены в нуль), если воспользоваться оператором GRANT
с любым из
приведенных выше пунктов, включая оператор GRANT
с текущими значениями.
Кроме того, текущие значения для всех пользователей сбрасываются, если
производится перезагрузка привилегий (на сервере или при использовании
команды mysqladmin reload
) или если выполняется команда FLUSH
USER_RESOURCES
.
Эта функция включается сразу после того, как на пользователя будут
наложены ограничения при помощи команды GRANT
.
Необходимым условием для включения данной функции является наличие в
таблице user
базы данных mysql
дополнительного столбца, как это определено
в скриптах создания таблиц mysql_install_db
и mysql_install_db.sh
в
подкаталоге `scripts'.
4.3.7 Задание паролей
В большинстве случаев для задания пользователей и их паролей следует
пользоваться командой GRANT
, поэтому приведенная ниже информация
предназначена для опытных пользователей. See section 4.3.1 Синтаксис команд GRANT
и REVOKE
.
В примерах, приведенных в предыдущих разделах, демонстрируется важный
принцип, который заключается в следующем: при сохранении непустых паролей
с использованием операторов INSERT
или UPDATE
для их шифрования должна
применяться функция PASSWORD()
. Это делается потому, что в таблице user
пароли хранятся в зашифрованном виде, а не как простой текст. Предположим,
что мы упустили это из виду и задали пароли следующим образом:
shell> mysql -u root mysql mysql> INSERT INTO user (Host,User,Password) -> VALUES('%','jeffrey','biscuit'); mysql> FLUSH PRIVILEGES;
В результате выполнения этих команд в таблице user будет сохранено
значение пароля biscuit
в виде простого текста. Когда пользователь jeffrey
попытается подсоединиться к серверу, используя этот пароль, клиент mysql
зашифрует его при помощи функции PASSWORD()
, сгенерирует вектор
аутентификации, основанный на зашифрованном пароле и случайно выбранном
числе, полученном от сервера, и направит результат на сервер. Сервер
использует значение password
из таблицы user
(в данном случае, это
незашифрованное значение biscuit
), чтобы осуществить точно такие же
вычисления, и сравнит результаты. Результаты не совпадут, и сервер не
позволит установить соединение:
shell> mysql -u jeffrey -pbiscuit test Access denied
Перед занесением в таблицу user
пароли необходимо зашифровывать, поэтому
оператор INSERT
должен использоваться следующим образом:
mysql> INSERT INTO user (Host,User,Password) -> VALUES('%','jeffrey',PASSWORD('biscuit'));
При использовании оператора SET PASSWORD
также необходимо применять
функцию PASSWORD()
:
mysql> SET PASSWORD FOR jeffrey@"%" = PASSWORD('biscuit');
Если пароль задается при помощи оператора GRANT ... IDENTIFIED BY
или
команды mysqladmin password
, нет необходимости использовать функцию
PASSWORD()
. Обе эти команды самостоятельно производят шифровку пароля,
поэтому пароль следует указывать как biscuit
, например, таким образом:
mysql> GRANT USAGE ON *.* TO jeffrey@"%" IDENTIFIED BY 'biscuit';
или
shell> mysqladmin -u jeffrey password biscuit
Примечание: Функция PASSWORD()
шифрует пароли отличным от Unix образом. Не
следует полагать, что если ваши пароли для Unix и для MySQL совпадают, то
функция PASSWORD()
выдаст точно такой же результат шифрования, как и файл
паролей Unix. See section 4.3.2 Имена пользователей MySQL и пароли.
4.3.8 Обеспечение безопасности своего пароля
Не рекомендуется указывать пароль таким образом, чтобы его могли подобрать другие пользователи. Ниже приведены методы, которыми можно пользоваться при задании своего пароля при запуске указанных клиентских программ, а также степенью риска для каждого из методов:
-
Никогда не заносите пароль обычного доступа в таблицу
mysql.user
. Зная даже зашифрованный пароль пользователя, можно войти в систему под именем этого пользователя. Пароли шифруются только для того, чтобы нельзя было увидеть, какой именно пароль используется (если вы используете один и тот же пароль для разных приложений). -
Использование параметров
-pyour_pass
или--password=your_pass
в командной строке удобно, но не очень безопасно, так как ваш пароль становится видимым для системных статусных утилит (таких какps
), и другие пользователи могут просмотреть командные строки (во время запуска клиенты MySQL обычно перезаписывают аргументы командной строки нулями, но существует небольшой промежуток времени, на протяжении которого значение остается видимым). -
Используйте параметр
-p
или--password
(без указания значенияyour_pass
). В этом случае программа клиента запрашивает пароль с терминала:shell> mysql -u user_name -p Enter password: ********
Ваш пароль будет представлен символами `*'. Вводить пароль таким образом намного безопаснее, чем из командной строки, поскольку он невидим для остальных пользователей. Тем не менее, этот метод подходит только для тех программ, которые вы запускаете самостоятельно. Если клиент требуется запустить из скрипта, то возможности ввести пароль с терминала не будет. В некоторых системах первая строка скрипта считывается и неправильно распознается как ваш пароль! -
Храните свой файл в файле конфигурации. Например, можно записать свои
пароли в разделе
[client]
файла `.my.cnf' в своем каталоге:[client] password=your_pass
Если пароль хранится в `.my.cnf', файл не должен быть доступен для чтения или записи для всех или для отдельных групп пользователей. Убедитесь, что права доступа к файлу установлены в 400 или 600. -
Можно хранить свой пароль в переменной окружения
MYSQL_PWD
, но этот метод считается очень небезопасным и не должен использоваться. В некоторые версии ps включена возможность отображать переменные окружения работающего процесса. Поэтому если задать свой пароль при помощиMYSQL_PWD
, он будет виден для всех,. Даже в системах без такой версииps
, неразумно предполагать, что не существует другого метода получить информацию по переменным окружения. See section E Переменные окружения.
Исходя из всего сказанного выше, самыми безопасными методами указания пароля являются запрос программы клиента на ввод пароля с терминала или указание пароля в защищенном надлежащим образом файле `.my.cnf'.
4.3.9 Использование безопасных соединений
4.3.9.1 Основные сведения
MySQL поддерживает шифрованные SSL-соединения. Для лучшего понимания того, как в MySQL используется SSL, мы приводим здесь основные сведения по SSL и X509. Пользователи, которые уже знакомы с данным протоколом и стандартом, эту часть могут пропустить.
По умолчанию в MySQL используются незашифрованные соединения между клиентом и сервером. Это означает, что просматривать все данные, передаваемые между клиентом и сервером, может кто угодно. На практике можно даже изменять данные во время передачи их от клиента к серверу и наоборот. Помимо того, иногда возникает необходимость передать действительно секретные данные через общедоступную сеть - в таких случаях использование незашифрованных соединений просто неприемлемо.
В протоколе SSL используются различные алгоритмы шифрования, обеспечивающие безопасность для данных, передаваемых через общедоступные сети. Этот протокол содержит средства, позволяющие обнаруживать любые изменения, потери и повторы данных. В протоколе SSL также применяются алгоритмы для проведения идентификации при помощи стандарта X509.
Шифровка - это метод, позволяющий сделать прочтение любых данных невозможным. Фактически при современном положении дел для алгоритмов шифрования требуется использование дополнительных элементов безопасности. Они должны обеспечивать противодействие многим видам известных на настоящий момент атак, таких как изменение порядка зашифрованных сообщений или повторение данных.
Стандарт X509 позволяет производить идентификацию в Internet. Чаще всего он используется в приложениях электронной коммерции. Упрощенно схема его применения выглядит следующим образом: существует некая организация под названием "Certificate Authority" (можно перевести как ``Сертификационное Бюро''. - Прим. пер.), которая назначает электронные сертификаты всем, кому они нужны. Сертификаты основываются на асимметричных алгоритмах шифрования, содержащих два ключа - публичный и секретный. Владелец сертификата может подтвердить свою личность, предъявив свой сертификат другой стороне. Сертификат состоит из публичного ключа владельца. Любые данные, зашифрованные при помощи этого публичного ключа могут быть расшифрованы только при помощи соответствующего секретного ключа, который находится у владельца сертификата.
В MySQL по умолчанию не используется шифрование при соединениях, так как это значительно замедляет обмен данными между клиентом и сервером. Любые дополнительные функции приводят к дополнительной нагрузке для компьютера, а шифрование данных требует интенсивной работы процессора, что может вызвать задержку выполнения основных задач MySQL. По умолчанию MySQL настроен на максимально быструю работу.
Если вы хотите получить дополнительную информацию о SSL/X509/шифровании, необходимо воспользоваться своим любимым поисковым сервером Internet и произвести поиск по словам, которые вас интересуют.
4.3.9.2 Требования
Для того чтобы SSL-соединения могли работать с MySQL, необходимо выполнить следующие действия:
- Установите библиотеку OpenSSL. Тестирование MySQL производилось с библиотекой OpenSSL 0.9.6. http://www.openssl.org/.
-
Выполните настройку компиляции MySQL (
configure
) при помощи параметров--with-vio --with-openssl
. -
Если используется старая версия MySQL, то необходимо обновить таблицу
mysql.user
путем добавления в нее определенных новых столбцов. Это можно сделать, запустив скриптmysql_fix_privilege_tables.sh
. -
Проверить, скомпилирована ли в запущенном сервере
mysqld
библиотека OpenSSL можно, убедившись, чтоSHOW VARIABLES LIKE 'have_openssl'
показываетYES
.
4.3.9.3 Создание SSL-сертификатов
Вот пример, как создаются SSL-сертификаты для MySQL:
DIR=`pwd`/openssl PRIV=$DIR/private mkdir $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 # Пример вывода: # Using configuration from /home/monty/openssl/openssl.cnf # Generating a 1024 bit RSA private key # ................++++++ # .........++++++ # writing new private key to '/home/monty/openssl/private/cakey.pem' # Enter PEM pass phrase: # Verifying password - Enter PEM pass phrase: # ----- # You are about to be asked to enter information that will be incorporated # into your certificate request. # What you are about to enter is what is called a Distinguished Name or a DN. # There are quite a few fields but you can leave some blank # For some fields there will be a default value, # If you enter '.', the field will be left blank. # ----- # Country Name (2 letter code) [AU]:FI # State or Province Name (full name) [Some-State]:. # Locality Name (eg, city) []: # Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB # Organizational Unit Name (eg, section) []: # Common Name (eg, YOUR name) []:MySQL admin # Email Address []: # # Создаем server-request и ключ # openssl req -new -keyout $DIR/server-key.pem -out \ $DIR/server-req.pem -days 3600 -config $DIR/openssl.cnf # Пример вывода: # Using configuration from /home/monty/openssl/openssl.cnf # Generating a 1024 bit RSA private key # ..++++++ # ..........++++++ # writing new private key to '/home/monty/openssl/server-key.pem' # Enter PEM pass phrase: # Verifying password - Enter PEM pass phrase: # ----- # You are about to be asked to enter information that will be incorporated # into your certificate request. # What you are about to enter is what is called a Distinguished Name or a DN. # There are quite a few fields but you can leave some blank # For some fields there will be a default value, # If you enter '.', the field will be left blank. # ----- # Country Name (2 letter code) [AU]:FI # State or Province Name (full name) [Some-State]:. # Locality Name (eg, city) []: # Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB # Organizational Unit Name (eg, section) []: # Common Name (eg, YOUR name) []:MySQL server # Email Address []: # # Please enter the following 'extra' attributes # to be sent with your certificate request # A challenge password []: # An optional company name []: # # Удаляем парольную фразу из ключа (опционально) # 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 # Пример вывода: # Using configuration from /home/monty/openssl/openssl.cnf # Enter PEM pass phrase: # Check that the request matches the signature # Signature ok # The Subjects Distinguished Name is as follows # countryName :PRINTABLE:'FI' # organizationName :PRINTABLE:'MySQL AB' # commonName :PRINTABLE:'MySQL admin' # Certificate is to be certified until Sep 13 14:22:46 2003 GMT (365 days) # Sign the certificate? [y/n]:y # # # 1 out of 1 certificate requests certified, commit? [y/n]y # Write out database with 1 new entries # Data Base Updated # # Создаем client request и ключ # openssl req -new -keyout $DIR/client-key.pem -out \ $DIR/client-req.pem -days 3600 -config $DIR/openssl.cnf # Пример вывода: # Using configuration from /home/monty/openssl/openssl.cnf # Generating a 1024 bit RSA private key # .....................................++++++ # .............................................++++++ # writing new private key to '/home/monty/openssl/client-key.pem' # Enter PEM pass phrase: # Verifying password - Enter PEM pass phrase: # ----- # You are about to be asked to enter information that will be incorporated # into your certificate request. # What you are about to enter is what is called a Distinguished Name or a DN. # There are quite a few fields but you can leave some blank # For some fields there will be a default value, # If you enter '.', the field will be left blank. # ----- # Country Name (2 letter code) [AU]:FI # State or Province Name (full name) [Some-State]:. # Locality Name (eg, city) []: # Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB # Organizational Unit Name (eg, section) []: # Common Name (eg, YOUR name) []:MySQL user # Email Address []: # # Please enter the following 'extra' attributes # to be sent with your certificate request # A challenge password []: # An optional company name []: # # Удаляем парольную фразу из ключа (опционально) # 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 # Пример вывода: # Using configuration from /home/monty/openssl/openssl.cnf # Enter PEM pass phrase: # Check that the request matches the signature # Signature ok # The Subjects Distinguished Name is as follows # countryName :PRINTABLE:'FI' # organizationName :PRINTABLE:'MySQL AB' # commonName :PRINTABLE:'MySQL user' # Certificate is to be certified until Sep 13 16:45:17 2003 GMT (365 days) # Sign the certificate? [y/n]:y # # # 1 out of 1 certificate requests certified, commit? [y/n]y # Write out database with 1 new entries # Data Base Updated # # Создаем такой 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 # # Тестируем MySQL mysqld --defaults-file=$DIR/my.cnf & mysql --defaults-file=$DIR/my.cnf
Вы также можете тестировать сертификаты путем модификации my.cnf
таким образом,
чтобы использовать демонстрационные сертификаты в каталоге mysql-source-dist/SSL
.
4.3.9.4 Параметры команды GRANT
В дополнение к обычной схеме имя пользователя/пароль MySQL может производить проверку атрибутов сертификата X509. Для этого необходимы также все обычные параметры (имя пользователя, пароль, маска IP-адреса, имя базы данных/таблицы).
Существует несколько возможностей ограничить соединения:
- Если не указано никаких параметров SSL/X509, а имя пользователя и пароль указаны правильно, то разрешены все виды шифрованных и нешифрованных соединений.
-
Параметр
REQUIRE SSL
позволяет серверу устанавливать только зашифрованные при помощи протокола SSL соединения. Обратите внимание, что этот параметр может быть неприемлемым, если существуют записи ACL, разрешающие не-SSL соединения.mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost -> IDENTIFIED BY "goodsecret" REQUIRE SSL;
-
REQUIRE X509
означает, что у клиента должен быть действительный сертификат, но мы не требуем наличия определенного сертификата, сертификата определенной фирмы или темы. Единственное ограничение - подпись должна поддаваться проверке при помощи одного из сертификатов бюро сертификации.mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost -> IDENTIFIED BY "goodsecret" REQUIRE X509;
-
REQUIRE ISSUER "issuer"
делает требования по соединению более определенными: теперь клиент должен предоставить действительный сертификат X509, выданный бюро сертификации (CA)"issuer"
. Использование сертификатов X509 всегда означает применение шифрования, поэтому параметрSSL
больше не нужен.mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost -> IDENTIFIED BY "goodsecret" -> REQUIRE ISSUER "C=FI, ST=Some-State, L=Helsinki, "> O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@mysql.com";
-
REQUIRE SUBJECT "subject"
требует наличия у клиента действительного сертификата X509 с содержащейся в нем темой "subject". Если у клиента есть действительный сертификат, но другой "subject", то соединение не будет установлено.mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost -> IDENTIFIED BY "goodsecret" -> REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn, "> O=MySQL demo client certificate, "> CN=Tonu Samuel/Email=tonu@mysql.com";
-
REQUIRE CIPHER "cipher"
требуется для обеспечения достаточно сложных шифра и длины ключа. Протокол SSL сам по себе может быть ненадежным из-за использования старых алгоритмов с короткими ключами шифрования. Воспользовавшись этим параметром, мы можем указать определенный метод шифрования, разрешающий соединение.mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost -> IDENTIFIED BY "goodsecret" -> REQUIRE CIPHER "EDH-RSA-DES-CBC3-SHA";
Разрешается также сочетатьSUBJECT
,ISSUER
,CIPHER
вREQUIRE
, например, так:mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost -> IDENTIFIED BY "goodsecret" -> REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn, "> O=MySQL demo client certificate, "> CN=Tonu Samuel/Email=tonu@mysql.com" -> AND ISSUER "C=FI, ST=Some-State, L=Helsinki, "> O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@mysql.com" -> AND CIPHER "EDH-RSA-DES-CBC3-SHA";
Начиная с MySQL 4.0.4, словоAND
необязательно в опцияхREQUIRE
. Порядок опций не имеет значения, но ни одна опция не может быть указана дважды.
4.4 Предотвращение катастроф и восстановление
4.4.1 Резервное копирование баз данных
Поскольку таблицы MySQL хранятся в виде файлов, то резервное копирование
выполняется легко. Чтобы резервная копия была согласованной, выполните на
выбранных таблицах LOCK TABLES
, а затем FLUSH TABLES
для этих таблиц (см.
разделы section 6.7.2 Синтаксис команд LOCK TABLES/UNLOCK TABLES
и see section 4.5.3 Синтаксис команды FLUSH
). При этом
требуется блокировка только на чтение; поэтому другие потоки смогут
продолжать запросы на таблицах в то время, пока будут создаваться копии
файлов из каталога базы данных. Команда FLUSH TABLE
обеспечивает гарантию
того, что все активные индексные страницы будут записаны на диск прежде,
чем начнется резервное копирование.
Начиная с 3.23.56 и 4.0.12 BACKUP TABLE
не позволит вам перезаписать существующие
файлы, так как это создает потенциальные проблемы в безопасности.
Если есть необходимость провести резервное копирование на уровне SQL, то
можно воспользоваться SELECT INTO OUTFILE
или BACKUP TABLE
(см. разделы
section 6.4.1 Синтаксис оператора SELECT
и see section 4.4.2 Синтаксис BACKUP TABLE
).
Существует еще один способ создать резервную копию базы данных -
использовать программу mysqldump
или сценарий mysqlhotcopy
(см. разделы
section 4.8.5 mysqldump
, Получение дампов данных и структуры таблицы и see section 4.8.6 mysqlhotcopy
, Копирование баз данных и таблиц MySQL). Для этого нужно выполнить следующие действия:
-
Сделать полное резервное копирование баз данных:
shell> mysqldump --tab=/path/to/some/dir --opt --all или shell> mysqlhotcopy database /path/to/some/dir
Можно также просто скопировать табличные файлы (файлы `*.frm', `*.MYD' и `*.MYI') в тот момент, когда сервер не проводит никаких обновлений. Этот метод используется в сценарииmysqlhotcopy
. -
Если
mysqld
выполняется, остановить его, и затем запустить с опцией--log-update[=file_name]
(see section 4.9.3 Журнал обновлений (update)). В файлах журнала обновлений находится информация, необходимая для того, чтобы повторить в базе данных последовательность изменений, внесенных с момента выполненияmysqldump
.
Если дело дошло до восстановления, сначала надо попробовать восстановить
таблицы с помощью REPAIR TABLE
или myisamchk -r
- это должно сработать в
99,9% случаев. Если myisamchk
не даст результата, попробуйте применить
следующую процедуру (эти действия применимы только в случае, если MySQL
запускался с --log-update
(see section 4.9.3 Журнал обновлений (update))):
-
Восстановите исходный вариант по копии, сделанной в
mysqldump
. -
Выполните следующую команду, чтобы повторить обновления из бинарного
журнала:
shell> mysqlbinlog hostname-bin.[0-9]* | mysql
Если используется журнал обновлений, то можно применить:shell> ls -1 -t -r hostname.[0-9]* | xargs cat | mysql
ls
используется для того, чтобы расположить все файлы журнала обновлений в
правильном порядке.
Можно проводить избирательное резервное копирование посредством SELECT *
INTO OUTFILE 'file_name' FROM tbl_name
, а восстановление - при помощи LOAD
DATA INFILE 'file_name' REPLACE ...
Чтобы избежать повторения записей, в
таблице должен быть первичный
или уникальный ключ
. Ключевое слово REPLACE
задает замену старых записей новыми в случае, когда новая запись в
значении уникального ключа повторяет старую.
Если в системе, где выполняется резервное копирование, возникают проблемы с производительностью, то решить их можно, установив репликацию и выполняя резервное копирование на подчиненном сервере вместо головного (see section 4.10.1 Введение).
Пользователи файловой системы Veritas могут поступить следующим образом:
-
Из клиента (или Perl) выполнить:
FLUSH TABLES WITH READ LOCK
. -
Из другого shell выполнить:
mount vxfs snapshot
. -
Из первого клиента выполнить:
UNLOCK TABLES
. - Скопировать файлы из образа.
- Демонтировать образ.
4.4.2 Синтаксис BACKUP TABLE
BACKUP TABLE tbl_name[,tbl_name...] TO '/path/to/backup/directory'
Копирует в каталог резервного копирования тот минимум табличных файлов, который
достаточен для восстановления таблицы, после сброса на диск всех изменений. На
данный момент работает только для таблиц MyISAM
. Для таблиц
MyISAM
копирует файлы `.frm' (определений) и `.MYD' (данных).
Индексные файлы могут быть реконструированы по этим двум.
Перед использованием этой команды, пожалуйста, ознакомьтесь с разделом See section 4.4.1 Резервное копирование баз данных.
В процессе резервного копирования будет установлена блокировка чтения
отдельно для каждой таблицы на время ее копирования. Если необходимо
сделать резервное копирование в виде мгновенного образа нескольких таблиц,
необходимо сначала запросить LOCK TABLES
установки блокировки чтения для
каждой таблицы в группе.
Команда возвращает таблицу со следующими столбцами:
Столбец | Значение |
Table | Имя таблицы |
Op | Всегда ``backup'' |
Msg_type | Одно из значений status , error , info или warning .
|
Msg_text | Само сообщение. |
Заметим, что BACKUP TABLE
доступна только в версии MySQL 3.23.25 и выше.
4.4.3 Синтаксис RESTORE TABLE
RESTORE TABLE tbl_name[,tbl_name...] FROM '/path/to/backup/directory'
Восстанавливает таблицу(ы) из резервной копии, созданной с помощью BACKUP
TABLE
. Существующие таблицы не перезаписываются: при попытке
восстановления поверх существующей таблицы будет выдана ошибка.
Восстановление занимает больше времени, нежели BACKUP
- из-за
необходимости повторного построения индекса. Чем больше в таблице будет
ключей, тем больше времени заберет реконструкция. Эта команда, так же как
и BACKUP TABLE
, в настоящее время работает только для таблиц MyISAM
.
Команда возвращает таблицу со следующими столбцами:
Столбец | Значение |
Table | Имя таблицы |
Op | Всегда ``restore'' |
Msg_type | Одно из значений status , error , info или warning .
|
Msg_text | Само сообщение. |
4.4.4 Синтаксис CHECK TABLE
CHECK TABLE tbl_name[,tbl_name...] [option [option...]] option = QUICK | FAST | MEDIUM | EXTENDED | CHANGED
CHECK TABLE
работает только на таблицах MyISAM
и InnoDB
. На таблицах типа
MyISAM
команда эквивалентна запуску на таблице myisamchk -m table_name
.
Если опция не указана, используется MEDIUM
.
Проверяет таблицу(ы) на наличие ошибок. Для таблиц MyISAM
обновляется
статистика ключей. Команда возвращает таблицу со следующими столбцами:
Столбец | Значение |
Table | Имя таблицы. |
Op | Всегда ``check''. |
Msg_type | Одно из значений status , error , info , или warning .
|
Msg_text | Само сообщение. |
Заметим, что по каждой проверяемой таблице может быть выдано много строк
информации. Последняя строка будет представлять Msg_type status
и, как
правило, должна содержать OK
. Если выдается что-либо отличное от
OK
и Not checked
, то обычно следует провести ремонт таблицы
(see section 4.4.6 Использование myisamchk
для профилактики таблиц и послеаварийного). Table already up to date
свидетельствует о
том, что указанный для таблицы тип (TYPE
) вернул информацию о том, что
таблица не нуждается в проверке.
Различные типы проверки означают следующее:
Тип | Действия |
QUICK | Не сканировать строки для проверки на неправильные связи. |
FAST | Проверять только таблицы, которые не были корректно закрыты. |
CHANGED | Проверять только таблицы, которые изменились со времени последней проверки или не были закрыты корректно. |
MEDIUM | Сканировать строки для проверки того, что уничтоженные связи в порядке. При этом также подсчитывается ключевая контрольная сумма для строки и сравнивается с подсчитанной контрольной суммой для ключей. |
EXTENDED | Выполнить полный просмотр ключа для всех ключей для каждой строки. Успех такой проверки гарантирует 100%-ное отсутствие противоречий в таблице, но на проверку уйдет немало времени! |
Для таблиц MyISAM
с динамическими размерами при запуске проверки всегда
выполняется проверка MEDIUM
. Для строк со статическими размерами мы
пропускаем сканирование строк для QUICK
и FAST
, поскольку повреждение
строк происходит крайне редко.
Проверочные опции можно сочетать:
CHECK TABLE test_table FAST QUICK;
Эта команда просто вызовет быструю проверку таблицы для выявления того, была ли она закрыта корректно.
Примечание: в некоторых случаях CHECK TABLE
изменяет таблицу! Это
происходит, если таблица помечена как 'поврежденная/corrupted' или 'не
закрытая корректно/not closed properly', а CHECK TABLE
не находит никаких
проблем в таблице. В этом случае CHECK TABLE
отметит в таблице, что с ней
все нормально.
Если таблица повреждена, то, скорее всего, проблема в индексах, а не в данных. Проверки всех типов обеспечивают всестороннюю проверку индексов и тем самым должны обнаруживать большинство ошибок.
Если проверяется таблица, с которой предположительно все нормально, то
можно опустить проверочные опции или указать опцию QUICK
. Последнюю
возможность следует использовать в случае ограничений по времени и тогда,
когда можно пойти на риск (очень незначительный), что QUICK
пропустит
ошибку в файле данных. (В большинстве случаев MySQL должен найти - при
нормальной работе - любые ошибки в файле с данными. Если ошибки найдены,
то таблица будет отмечена как 'поврежденная/corrupted', и в таком случае
ее нельзя будет использовать, пока она не будет исправлена.)
FAST
и CHANGED
главным образом предназначены для использования в сценариях
(например, для запуска из cron
), если необходимо время от времени
проверять таблицы. В большинстве случаев следует отдавать предпочтение
FAST
перед CHANGED
(иначе надо поступать только в случае, когда возникает
подозрение, что найдена ошибка в самом коде MyISAM
).
Прибегать к EXTENDED
следует только тогда, когда после выполнения
нормальной проверки для таблицы по-прежнему выдаются странные ошибки при
попытке MySQL обновить строку или найти строку по ключу (что очень
маловероятно в случае успеха нормальной проверки!).
Некоторые проблемы, о которых сообщается при проверке таблицы, нельзя исправить автоматически:
-
Found row where the auto_increment column has the value 0
. Это означает, что в таблице есть строка, где индексированный столбецAUTO_INCREMENT
содержит значение 0 (строку, в которой столбецAUTO_INCREMENT
имеет значение 0, можно создать, явно установив столбец в 0 командойUPDATE
). Это само по себе не является ошибкой, но может вызвать неприятности, если понадобится сделать дамп таблицы или восстановить ее или выполнить над нейALTER
TABLE. В этом случае столбец с атрибутомAUTO_INCREMENT
изменит значение в соответствии с правилами для столбцовAUTO_INCREMENT
, что может вызвать проблемы, подобные ошибке дублирования ключа. Чтобы избавиться от предупреждения, просто выполните командуUPDATE
для установки в столбце значения, отличного от 0.
4.4.5 Синтаксис REPAIR TABLE
REPAIR TABLE tbl_name[,tbl_name...] [QUICK] [EXTENDED] [USE_FRM]
REPAIR TABLE
работает только на таблицах типа MyISAM
и эквивалентна
выполнению на таблице myisamchk -r table_name
.
При обыкновенной работе запускать эту команду не приходится, но если
случится катастрофа, то с помощью REPAIR TABLE
практически наверняка
удастся вернуть все данные из таблицы MyISAM
. Если таблицы сильно
повреждены, то следует постараться выяснить, что послужило этому причиной!
Обращайтесь к разделам section A.4.1 Что делать, если работа MySQL сопровождается постоянными сбоями и See section 7.1.3 Проблемы с таблицами MyISAM
..
REPAIR TABLE
ремонтирует таблицу, которая, возможно, повреждена. Команда
возвращает таблицу со следующими столбцами:
Столбец | Значение |
Table | Имя таблицы |
Op | Всегда ``repair'' |
Msg_type | Одно из значений status , error , info или warning .
|
Msg_text | Само сообщение. |
Заметим, что по каждой ремонтируемой таблице может быть выдано много строк
информации. Последняя строка будет представлять Msg_type status
и, как
правило, должна содержать OK
. Если выдается что-либо отличное от OK
, то
следует попробовать исправить таблицу с помощью myisamchk -o
, поскольку в
REPAIR TABLE
пока реализованы не все опции myisamchk
. В скором будущем мы
сделаем команду более гибкой.
Если указан QUICK
, то MySQL будет пытаться сделать REPAIR
только
индексного дерева.
Если используется EXTENDED
, то MySQL будет создавать индекс строка за
строкой вместо создания по одному индексу единоразово с помощью
сортировки; такая техника может работать лучше сортировки для ключей
фиксированной длины, если речь идет о хорошо сжимаемых ключах типа CHAR
большой длины. Это такой же ремонт, как делается с помощью myisamchk --safe-recover
.
Что касается MySQL 4.0.2, то тут для REPAIR
существует режим USE_FRM
.
Используйте его, если отсутствует файл `.MYI' или поврежден его заголовок. В
этом режиме MySQL воссоздаст таблицу, используя информацию из файла `.frm'.
Этот вид исправления в myisamchk
недоступен.
4.4.6 Использование myisamchk
для профилактики таблиц и послеаварийного
восстановления
Начиная с версии MySQL 3.23.13 таблицы MyISAM
можно проверять с помощью
команды CHECK TABLE
(see section 4.4.4 Синтаксис CHECK TABLE
). Для исправления
таблиц используется команда REPAIR TABLE
(see section 4.4.5 Синтаксис REPAIR TABLE
).
Для проверки/ремонта таблиц типа MyISAM
(`.MYI' и `.MYD') следует использовать
утилиту myisamchk
, а для ISAM
(`.ISM' и `.ISD'') - утилиту isamchk
(see section 7 Типы таблиц MySQL).
Ниже мы будем говорить о myisamchk
, но все сказанное справедливо также и
для более старой isamchk
.
Утилиту myisamchk
можно использовать для получения информации о таблицах
рабочей базы данных, для их проверки и исправления или же оптимизации. В
следующих разделах описывается, как запускать myisamchk
(включая описание
ее опций), как настроить график профилактики таблицы и как использовать
myisamchk для выполнения различных функций.
В большинстве случаев для оптимизации и исправления таблиц можно также
использовать команду OPTIMIZE
TABLES, но этот вариант не такой быстрый и
не такой надежный (в случае действительно фатальных ошибок), как
myisamchk
. С другой стороны, OPTIMIZE TABLE
проще в использовании и
освобождает от забот со сбросом таблиц на диск (see section 4.5.1 Синтаксис команды OPTIMIZE TABLE
).
Хотя исправление при помощи myisamchk
и достаточно безопасно, никогда не
будет лишним сделать резервную копию прежде, чем выполнять ремонт (или
любые другие действия, которые могут привнести в таблицу значительные
изменения)
4.4.6.1 Синтаксис запуска myisamchk
myisamchk
запускается следующим образом:
shell> myisamchk [options] tbl_name
Опции options определяют, что должна сделать myisamchk
. В данном разделе
дается описание этих опций (список опций можно также получить, запустив
myisamchk --help
). Если опции не указаны, myisamchk
просто проверяет
таблицу. Чтобы получить дополнительную информацию или указать myisamchk
выполнить корректирующие действия, надо задать опции, как это описано в
этом и в следующих разделах.
tbl_name
- это таблица базы данных, которую нужно проверить/исправить.
Если myisamchk
запускается не из каталога базы данных, то следует задать
путь к файлу, поскольку myisamchk
не имеет представления о том, где искать
базу данных. В действительности для myisamchk
не важно, где находятся
рабочие файлы - в каталоге базы данных или нет; можно скопировать файлы,
относящиеся к базе данных, в другое место и выполнить операции
восстановления над ними там.
При желании в командной строке myisamchk
можно перечислить имена
нескольких таблиц. В качестве имени можно также указать имя индексного
файла (с суффиксом `.MYI'), что позволит задавать все таблицы в каталоге при
помощи шаблона `*.MYI'. Например, находясь в каталоге базы данных, можно
проверить все таблицы этого каталога следующим образом:
shell> myisamchk *.MYI
Если каталог базы данных не является текущим, то все таблицы каталога можно проверить, указав к нему путь:
shell> myisamchk /path/to/database_dir/*.MYI
Можно даже проверить все таблицы во всех базах данных, если задать шаблон вместе с путем к каталогу данных MySQL:
shell> myisamchk /path/to/datadir/*/*.MYI
Быстро проверять все таблицы рекомендуется следующим образом:
myisamchk --silent --fast /path/to/datadir/*/*.MYI isamchk --silent /path/to/datadir/*/*.ISM
Если необходимо проверить все таблицы и исправить все поврежденные из них, можно использовать следующую строку:
myisamchk --silent --force --fast --update-state -O key_buffer=64M \ -O sort_buffer=64M -O read_buffer=1M -O write_buffer=1M \ /path/to/datadir/*/*.MYI isamchk --silent --force -O key_buffer=64M -O sort_buffer=64M \ -O read_buffer=1M -O write_buffer=1M /path/to/datadir/*/*.ISM
Эти команды предполагают, что имеется более чем 64 Mб свободного пространства.
Следует отметить, что если выдается ошибка, подобная следующей:
myisamchk: warning: 1 clients is using or hasn't closed the table properly
то это означает, что делается попытка проверить таблицу, обновленную
другой программой (такой как mysqld
), которая еще не закрыла файл или чье
выполнение было прервано без возможности корректно закрыть файл.
Если mysqld
запущен, то необходимо принудительно вызвать
синхронизацию/закрытие всех таблиц с помощью FLUSH TABLES
и обеспечить,
чтобы никто не использовал таблиц, пока выполняется myisamchk
. В версии
MySQL 3.23 самый простой способ избежать этой проблемы заключается в
применении для проверки таблиц команды CHECK TABLE
вместо myisamchk
.
4.4.6.2 Общие опции для myisamchk
myisamchk
поддерживает следующие опции.
-# или --debug=debug_options
-
Вывод отладочной информации. Часто строка
debug_options
имеет следующий видd:t:o,filename
. -? или --help
- Отображение справочного сообщения с завершением работы.
-O var=option, --set-variable var=option
-
Устанавливает значение переменной. Внимание:
--set-variable
морально устарела в MySQL 4.0, просто используйте--var=option
. Вывести список допустимых переменных и их значений по умолчанию дляmyisamchk
можно с помощьюmyisamchk --help
:Переменная Значение key_buffer_size 523264 read_buffer_size 262136 write_buffer_size 262136 sort_buffer_size 2097144 sort_key_blocks 16 decode_bits 9 sort_buffer_size
применяется, когда ключи исправляются посредством сортировки ключей (обычный случай при указании--recover
), аkey_buffer_size
- если таблица проверяется с--extended-check
или если ключи исправляются посредством вставки ключей в таблицу построчно (как при выполнении обычных вставок). Исправление через ключевой буфер применяется в следующих случаях:-
Если используется
--safe-recover
. -
Если размер требуемых для сортировки временных файлов будет более чем
вдвое превышать объем, требующийся при создании ключевого файла
непосредственно. Так часто обстоит дело, когда присутствуют большие ключи
типов
CHAR
,VARCHAR
илиTEXT
, поскольку при сортировке необходимо сохранять ключи целиком. Имея временное пространство на диске в избытке, можно заставитьmyisamchk
делать исправления посредством сортировки, задав опцию--sort-recover
.
-
Если используется
-s или --silent
-
Молчаливый режим. Выдавать сообщения только при возникновении ошибок.
Можно использовать
-s
дважды (-ss
), чтобы предельно ограничить выдачу сообщений утилитойmyisamchk
. -v или --verbose
-
Расширенный режим вывода. Выдается больше информации. Можно использовать с
-d
и-e
. Можно использовать-v
многократно (-vv
,-vvv
) - чтобы еще более расширить сводку! -V или --version
-
Отображение версии
myisamchk
и завершение работы. -w или, --wait
-
Если таблица заблокирована, то не выдавать ошибки, а, дождавшись снятия
блокировки с таблицы, продолжить выполнение. Заметим, что если
mysqld
выполняется на таблице с--skip-external-locking
, то таблица может быть заблокирована только другой командойmyisamchk
.
4.4.6.3 Проверочные опции для myisamchk
-c или --check
-
Проверить таблицы на ошибки. Является операцией по умолчанию, если
myisamchk
не передаются другие опции, меняющие это поведение. -e или --extend-check
-
Проверить таблицу очень тщательно (выполняется достаточно медленно в
случае большого количества индексов). Эту опцию следует использовать в
экстремальных ситуациях. В большинстве случаев
myisamchk
илиmyisamchk
--medium-check
вполне достаточно для выявления ошибок в таблице. Если используется--extended-check
и система располагает приличным объемом памяти, то следует значительно увеличить значениеkey_buffer_size
! -F или --fast
- Проверять только таблицы, которые не были корректно закрыты.
-C или --check-only-changed
- Проверять только таблицы, изменившиеся с момента последней проверки.
-f или --force
-
Выполнять перезапуск
myisamchk
с-r
(исправить) на таблице, еслиmyisamchk
найдет в ней хоть одну ошибку. -i или --information
- Выдавать статистическую информацию о проверяемой таблице.
-m или --medium-check
-
Быстрее, чем расширенная проверка (
extended-check
), но при этом обнаруживается только 99,99% из общего числа ошибок (чего, однако, в большинстве случаев вполне достаточно). -U или --update-state
-
Отмечать в файле `.MYI' факт проверки таблицы и наличие повреждений. Опцию
следует использовать для получения максимального эффекта от опции
--check-only-changed
, однако ее применение недопустимо, еслиmysqld
работает с таблицей и был запущен с опцией--skip-external-locking
. -T или --read-only
-
Не отмечать таблицу как проверенную. Это может пригодиться, когда
myisamchk используется для проверки таблиц, используемых каким-то другим
приложением, и это приложение не выполняет блокировку (как
mysqld --skip-external-locking
).
4.4.6.4 Опции исправления для myisamchk
Следующие опции используются, если myisamchk
запускается с -r
или -o
:
- -D # или --data-file-length=# Максимальная длина файла данных (когда файл данных пересоздается при его ``переполнении'').
- -e или --extend-check Пробовать исправлять каждую возможную строку из файла данных. Обычно при этом обнаруживается масса замусоренных строк. Использовать эту опцию следует только в самом крайнем случае, когда больше ничего не остается.
- -f или --force Писать поверх старых временных файлов (`table_name.TMD') вместо аварийного прекращения.
-
-k # или keys-used=#
Если используется
ISAM
, то данный параметр предписывает обработчику таблицISAM
на необходимость обновить только первые#
индексов. Если используетсяMyISAM
, то определяет, какие ключи использовать, при этом каждый двоичный бит соответствует одному ключу (первый ключ - это бит 0). Может использоваться для ускорения вставок! Отключенные индексы можно снова активизировать с помощьюmyisamchk -r. keys
. -
-l или --no-symlinks
Не рассматривать символические ссылки. Обычно
myisamchk
исправляет таблицы, на которые указывают символические ссылки. Данная опция отсутствует в MySQL 4.0, в связи с тем, что MySQL 4.0 не удаляет символические ссылки во время восстановления. -
-r или --recover
При указании этой опции можно исправить практически все, кроме уникальных ключей, в которых есть повторения (ошибка, вероятность которой мизерна для таблиц
ISAM
/MyISAM
). Если необходимо восстановить таблицу, то начинать надо с этой опции. Только еслиmyisamchk
сообщит, что таблица не может быть восстановлена с помощью-r
, тогда следует пытаться применять-o
(отметим, что в тех маловероятных случаях, когда-r
не срабатывает, файл данных остается неизменным), В случае большого объема памяти следует увеличить размерsort_buffer_size
! -o или --safe-recover
-
Используется старый метод восстановления (читаются подряд все строки и
обновляются все деревья индексов на основе найденных строк); такой
алгоритм работает на порядок медленнее
-r
, но метод справляется с несколькими редкими случаями, непосильными для-r
. При этом методе восстановления также используется значительно меньше дискового пространства, нежели в случае-r
. Обычно всегда следует начинать с исправления посредством-r
, и только если результат не будет достигнут, использовать-o
. Для систем с большим объемом памяти следует увеличить размерkey_buffer_size
! -n или --sort-recover
-
Заставляет
myisamchk
использовать сортировку при разрешении ключей, даже если это потребует временных файлов очень большого размера. --character-sets-dir=...
- Каталог, где хранятся кодировки.
--set-character-set=name
- Изменить используемую для индекса кодировку
-t или --tmpdir=path
-
Путь для хранения временных файлов. Если не задан,
myisamchk
использует для пути переменную окруженияTMPDIR
. Начиная с MySQL 4.1, вTMPDIR
могут быть указаны несколько путей, разделенных двоеточием:
(точкой с запятой на Windows;
). Эти пути будут использованы в ротации. Это используется для того, чтобы распределить данные между разными физическими дисками. -q или --quick
-
Быстрый ремонт без изменения файла данных. Можно добавить вторую
-q
, чтобы датьmyisamchk
санкцию на изменение исходного файла данных в случае дублирования ключей -u или --unpack
-
Распаковать файл, упакованный в
myisampack
.
4.4.6.5 Другие опции для myisamchk
Кроме ремонта и проверки таблиц, myisamchk
может выполнять другие
операции:
-a или --analyze
-
Анализировать распределение ключей. Улучшает эффективность операции
связывания за счет включения оптимизатора связей. Он обеспечивает лучший
порядок связывания таблиц и определяет, какие ключи при этом следует
использовать:
myisamchk --describe --verbose table_name
или посредствомSHOW KEYS
в MySQL. -d или --description
- Отображает некоторую информацию о таблице.
-A или --set-auto-increment[=value]
-
Предписывает, чтобы отсчет значений
AUTO_INCREMENT
начинался сvalue
или большего значения. Если значение не указано, то в качестве следующего значенияAUTO_INCREMENT
берется наибольшее использованное значение для автоинкрементного ключа + 1. -S или --sort-index
- Сортировать блоки индексного дерева в порядке от больших к меньшим (high-low). Этим оптимизируются операции поиска и повышается скорость сканирования по ключу.
-R или --sort-records=#
-
Сортирует записи в соответствии с индексом. Это значительно повышает
локализацию данных и может ускорить операции
SELECT
иORDER BY
, которые выполняются по индексу и выбирают данные по какому-либо интервалу. (Возможно, что первая сортировка будет выполняться очень медленно!) Чтобы узнать номера индексов таблицы, нужно использовать командуSHOW INDEX
, показывающую индексы таблицы в том же порядке, в каком их видитmyisamchk
. Индексы нумеруются начиная с 1.
4.4.6.6 Использование памяти утилитой myisamchk
При работе myisamchk
очень важно распределение памяти. Объем используемой
myisamchk
памяти не превышает количества, указанного с помощью опций -O
.
Когда речь идет о применении myisamchk
на очень больших файлах, следует
сначала принять решение о том, какое количество памяти будет при этом
использоваться. По умолчанию для целей исправления ошибок отводится только
около 3Mб. Применяя большие величины, можно достичь большей скорости
работы myisamchk
. К примеру, если имеется более 32Mб оперативной памяти,
то можно задать следующие опции (в дополнение к любым другим указанным опциям):
shell> myisamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...
В большинстве случаев достаточно использовать -O sort=16M
.
Важно понимать, что myisamchk
использует временные файлы, для указания на
которые служит TMPDIR
. Если TMPDIR
указывает на файловую систему с
размещением в памяти, то велика вероятность ошибок нехватки памяти (out of
memory). Если такое произойдет, то в TMPDIR
следует поместить имя
некоторого другого каталога с большим пространством и перезапустить
myisamchk
.
При выполнении ремонта myisamchk
также понадобится большое количество
дискового пространства; :
-
Потребуется пространство порядка удвоенного размера файла - для
оригинала и копии файла данных. В этом пространстве нет необходимости,
когда исправление выполняется с
--quick
, поскольку в этом случае повторно создается только индексный файл. Дополнительное место необходимо на том же диске, где находится оригинальный файл записи! - Необходимо место для нового индексного файла, заменяющего старый. В начальной фазе выполнения старый индексный файл усекается, поэтому обычно данный объем можно не учитывать. Место должно обеспечиваться на диске, содержащем оригинальный индексный файл!
-
При указании
--recover
или--sort-recover
(но не в случае использования--safe-recover
) потребуется место для буфера сортировки: (largest_key + row_pointer_length)*number_of_rows * 2
. Можно узнать длину ключей иrow_pointer_length
с помощьюmyisamchk -dv table
. Это пространство выделяется на временном диске (который определяется при помощиTMPDIR
либо--tmpdir=#
).
Если возникнут проблемы в связи с нехваткой дискового пространства во
время исправления, можно попробовать использовать --safe-recover
вместо
--recover
.
4.4.6.7 Использование myisamchk для послеаварийного восстановления
При выполнении mysqld
со --skip-external-locking
(установка по умолчанию в
некоторых системах, подобных Linux) применение myisamchk
для проверки
таблицы, когда она используется mysqld
, не совсем безопасно. Если есть
уверенность, что никто не обратится к таблицам через mysqld
во время
выполнения myisamchk
, то достаточно до начала проверки таблиц выполнить
mysqladmin flush-tables
, если нет - то на время проверки таблиц необходимо
приостановить mysqld
. При запуске myisamchk
в то время, когда mysqld
обновляет таблицы, может быть выдано предупреждение о повреждении таблицы
- даже в случае, если этого не произошло.
Если --skip-external-locking
не используется, то проверять таблицы с помощью
myisamchk
можно в любое время. Во время проверки все пытающиеся обновить
таблицу клиенты получат возможность сделать это, только дождавшись
готовности myisamchk
.
Если myisamchk
применяется для ремонта или оптимизации таблиц, то всегда
необходимо обеспечить отсутствие обращений сервера mysqld
к таблице (это
также относится к случаю использования --skip-external-locking
). Если mysqld
не
может быть приостановлен, то до myisamchk
, как минимум, надо выполнить
mysqladmin flush-tables
. Таблицы могут быть повреждены, если сервер и
myisamchk
обратятся к таблицам одновременно.
В данном разделе описывается, как выявлять повреждения данных в базах данных MySQL и что делать с повреждениями дальше. Если таблица повреждается часто, то надо постараться отыскать причину этих повреждений! Обращайтесь к разделу See section A.4.1 Что делать, если работа MySQL сопровождается постоянными сбоями.
Причины повреждения таблиц рассматриваются также в разделе по таблицам
MyISAM
. Обращайтесь к разделу See section 7.1.3 Проблемы с таблицами MyISAM
..
При выполнении послеаварийного восстановления важно понимать, что каждой
таблице tbl_name
в базе данных соответствуют три файла в каталоге базы
данных:
Файл | Назначение |
`tbl_name.frm' | Файл определения таблицы (формы) |
`tbl_name.MYD' | Файл данных |
`tbl_name.MYI' | Индексный файл |
Каждый из этих трех типов файлов ``имеет'' свои виды повреждений, но наиболее часто проблемы возникают с файлами данных и индексными файлами.
Во время своей работы myisamchk
построчно создает копию файла (данных)
`.MYD'. Стадия исправления завершается тем, что программа удаляет старый
файл `.MYD' и переименовывает новый путем присвоения ему имени исходного.
Если используется --quick
, myisamchk
не создает временного файла `.MYD', а,
исходя из предположения, что файл `.MYD' правилен, только формирует новый
индексный файл, никак не меняя файл `.MYD'. Это безопасно, поскольку
myisamchk
автоматически распознает, что файл `.MYD' запорчен, и в этом
случае прерывает исправление. Можно также задавать для myisamchk
две опции
--quick
. В этом случае myisamchk
не прерывается аварийно по некоторым
ошибкам (таким как дублирование ключа), а пытается исправить их путем
модификации файла `.MYD'. Обычно использование двух опций --quick
имеет
смысл только в случае, если свободного места на диске недостаточно для
выполнения нормального исправления. Тогда перед запуском myisamchk
следует
по крайней мере выполнить резервное копирование.
4.4.6.8 Как проверять таблицы на ошибки
Для проверки таблицы MyISAM
используются следующие команды:
myisamchk tbl_name
- Находит 99,99% всех ошибок. Не в состоянии отыскать повреждений, затрагивающих только файл данных (которые весьма необычны). Если необходимо только проверить таблицу, то обычно следует выполнить myisamchk без опций либо с одной из опций -s или --silent.
myisamchk -m tbl_name
- Находит 99,999% всех ошибок. Сначала на ошибки проверяются все индексные элементы, а затем читаются все строки подряд. Программа вычисляет контрольную сумму для всех ключей в строке и проверяет, совпадает ли она с контрольной суммой в индексном дереве.
myisamchk -e tbl_name
-
В этом случае выполняется полная и тщательная проверка всех данных (
-e
означает ``расширенная проверка''). Происходит тестовое чтение каждого ключа для каждой строки с целью контроля того, что ключи указывают на нужные строки. Для большой таблицы с множеством ключей на это может потребоваться много времени.myisamchk
обычно останавливается после обнаружения первой ошибки, но если желательно получить более подробную информацию, можно добавить опцию--verbose
(-v
) - таким образом выполнениеmyisamchk
будет продолжаться вплоть до максимума в 20 ошибок. При нормальной работе достаточно просто запуститьmyisamchk
(без аргументов за исключением имени таблицы). myisamchk -e -i tbl_name
-
Аналогична предыдущей команде, но опция
-i
указываетmyisamchk
дополнительно отображать некоторую статистическую информацию.
4.4.6.9 Как ремонтировать таблицы
В данном разделе рассматривается только использование myisamchk
на
таблицах MyISAM
(расширения `.MYI' и `.MYD'). Если же в системе применяются
таблицы ISAM
(расширения `.ISM' и `.ISD'), то следует пользоваться isamchk
.
Начиная с версии MySQL 3.23.14 можно ремонтировать таблицы MyISAM
при
помощи команды REPAIR TABLE
(see section 4.4.5 Синтаксис REPAIR TABLE
).
К симптомам повреждения таблицы относятся неожиданные прерывания выполнения запросов и появление следующих ошибок:
- `tbl_name.frm' is locked against change (Файл заблокирован для изменений)
- Can't find file `tbl_name.MYI' (Errcode: ###) (Не могу найти файл `tbl_name.MYI' (Ошибка: ###))
- Unexpected end of file (Неожиданно наступил конец)
- Record file is crashed (Файл записей испорчен)
-
Got error ### from table handler (Получена ошибка ### от дескриптора
таблицы). Для получения более подробной информации об ошибке можно
выполнить
perror
###. Чаще всего о проблемах с таблицей свидетельствуют следующие ошибки:shell> perror 126 127 132 134 135 136 141 144 145 126 = Index file is crashed / Wrong file format 127 = Record-file is crashed 132 = Old database file 134 = Record was already deleted (or record file crashed) 135 = No more room in record file 136 = No more room in index file 141 = Duplicate unique key or constraint on write or update 144 = Table is crashed and last repair failed 145 = Table was marked as crashed and should be repaired
Заметим, что ошибка 135 - 'no more room in record file' ('не осталось места в файле записей'), не может быть исправлена просто выполнением ремонта. В этом случае необходимо использовать следующую команду:ALTER TABLE table MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;
В других случаях следует выполнять ремонт таблиц. myisamchk
обычно может
обнаружить и исправить большинство неполадок.
Процесс ремонтирования включает до четырех описанных здесь стадий. Перед
тем как приступить к ремонту, необходимо выполнить `cd' в каталог базы
данных и проверить права доступа к табличным файлам. Файлы должны быть
доступны для чтения Unix-пользователю, от имени которого выполняется
mysqld
, (а также выполняющему ремонт, поскольку ему приходится обращаться
к проверяемым файлам). Если появится необходимость изменять файлы, то
проверяющий также должен иметь доступ для записи.
Если используется версия MySQL 3.23.16 и выше, то для проверки и ремонта
таблиц MyISAM
можно (и нужно) использовать команды CHECK
и REPAIR
(section 4.4.4 Синтаксис CHECK TABLE
и see section 4.4.5 Синтаксис REPAIR TABLE
).
Раздел руководства, посвященный сопровождению таблиц, содержит опции к
isamchk
/myisamchk
(see section 4.4.6 Использование myisamchk
для профилактики таблиц и послеаварийного).
Случаи, когда упомянутые команды не дают результата или желательно
использовать расширенные возможности, представленные в isamchk
/myisamchk
,
рассматриваются в следующем разделе.
Если ремонт таблицы планируется выполнять из командной строки то сначала
требуется остановить сервер. Следует отметить, что при выполнении
mysqladmin shutdown
с удаленного сервера mysqld
все еще будет некоторое
время работать после завершения mysqladmin
, пока не будут остановлены все
запросы и сброшены на диск все ключи.
Стадия 1: проверка таблиц
Выполните myisamchk *.MYI
или, если вы располагаете временем, myisamchk -e
*.MYI
. Используйте опцию -s
(молчаливый режим) для подавления ненужной
информации.
Если mysqld
остановлен, то следует использовать опцию --update-state
для
указания myisamchk
отмечать таблицы как 'проверенные'(checked).
Ремонтировать следует только те таблицы, для которых myisamchk
выдала
ошибки. Для таких таблиц следует перейти к стадии 2.
Если во время проверки будут получены странные ошибки (подобные out of
memory), или myisamchk
завершится аварийно, то перейдите к стадии 3.
Стадия 2: легкий безопасный ремонт
Примечание: если есть желание ускорить ремонт, рекомендуется добавить: -O
sort_buffer=# -O key_buffer=#
(где # примерно 1/4 от имеющейся памяти) во
всех командах isamchk
/myisamchk
.
Сначала надо попробовать запустить myisamchk -r -q tbl_name
(-r -q
означает "режим быстрого восстановления"). При этом будет сделана попытка
исправить индексный файл без изменения файла данных. Если в файле данных
содержится все необходимое, а удаленные связи указывают на правильные
позиции в файле данных, то команда должна дать результат и таблица будет
исправлена. Перейдите к ремонту следующей таблицы. В противном случае
следует выполнить следующие действия:
- Сделать резервную копию файла данных.
-
Использовать
myisamchk -r tbl_name
(-r
означает "режим восстановления"). При этом из файла данных будут удалены некорректные и уничтоженные записи, и будет заново создан индексный файл. -
Если на предыдущем шаге проблему решить не удастся, то используйте
myisamchk --safe-recover tbl_name
. В режиме безопасного восстановления используется старый метод восстановления, справляющийся с некоторыми случаями, которые оказываются не под силу для режима обычного исправления (но работает этот метод медленнее).
Если во время проверки будут получены странные ошибки (подобные out of
memory) или myisamchk
аварийно завершается, то перейдите к стадии 3.
Стадия 3: сложный ремонт
До этой стадии дело доходит, только если первый 16-килобайтный блок в индексном файле разрушен или содержит неверную информацию, либо когда индексный файл отсутствует. В этом случае необходимо создать новый индексный файл. Необходимо выполнить следующие действия:
- Переместить файл данных в какое-нибудь безопасное место.
-
Использовать файл описания таблицы для создания новых (пустых) файлов
- данных и индексного:
shell> mysql db_name mysql> SET AUTOCOMMIT=1; mysql> TRUNCATE TABLE table_name; mysql> quit
Если используемая версия SQL не располагаетTRUNCATE TABLE
, то взамен используетсяDELETE FROM table_name
. - Скопируйте старый файл данных на место недавно созданного (делать перемещение старого файла обратно на место нового нецелесообразно, поскольку в старом файле может снова возникнуть потребность, если что-то пойдет не так).
Вернитесь к стадии 2. myisamchk -r -q
теперь должна сработать (но
бесконечно повторять стадии не следует).
Что касается MySQL 4.0.2, то тут можно воспользоваться REPAIR ... USE_FRM
,
выполняющей всю эту процедуру автоматически.
Стадия 4: очень сложный ремонт
До этой стадии вы дойдете только в случае, если ко всему прочему запорчен и файл описания. Такого происходить не должно, поскольку файл описания после создания таблицы не изменяется. Выполните следующие действия:
-
Восстановите файл описания из резервной копии и перейдите к стадии 3.
Можно также восстановить индексный файл и вернуться к стадии 2. Во
втором случае начинать надо с
myisamchk -r
. - Если резервной копии нет, но точно известно, как таблица создавалась, то создается копия таблицы в другой базе данных. Новый файл данных удаляется, затем файл описания с индексным файлом перемещаются из другой базы данных в поврежденную. Таким образом вы получаете новый файл описания и индексный файл, не затрагивая при этом файла данных. Делается возврат к стадии 2 с попыткой воссоздать индексный файл.
4.4.6.10 Оптимизация таблиц
Чтобы объединить фрагментированные записи и избавиться от потерь
пространства, происходящих из-за удаления и обновления записей, нужно
запустить myisamchk
в режиме восстановления:
shell> myisamchk -r tbl_name
Такую же оптимизацию таблицы можно произвести, используя команду SQL
OPTIMIZE TABLE
. OPTIMIZE TABLE
выполняет ремонт таблицы и анализ ключей, а
также сортирует дерево индексов для ускорения поиска ключей. Вдобавок
сводится на нет нежелательное взаимодействие между утилитой и сервером,
поскольку при использовании OPTIMIZE TABLE
работу выполняет сам сервер.
Обращайтесь к разделу See section 4.5.1 Синтаксис команды OPTIMIZE TABLE
.
myisamchk
также располагает рядом других опций, которые можно использовать
для повышения производительности таблицы:
-S
,--sort-index
-R index_num
,--sort-records=index_num
-a
,--analyze
Полное описание опций можно найти в разделе See section 4.4.6.1 Синтаксис запуска myisamchk
.
4.4.7 Настройка режима профилактики таблиц
Начиная с версии MySQL 3.23.13 можно проверять таблицы типа MyISAM
с
помощью команды CHECK TABLE
(see section 4.4.4 Синтаксис CHECK TABLE
). Для ремонта
таблиц можно использовать команду REPAIR TABLE
(see section 4.4.5 Синтаксис REPAIR TABLE
).
Целесообразно выполнять регулярные проверки таблиц, не дожидаясь появления
проблем. В целях профилактики для проверки таблиц можно использовать
myisamchk -s
. Опция -s
(сокращение для --silent
) задает выполнение
myisamchk
в молчаливом режиме с выдачей сообщений только при возникновении
ошибок.
Не стоит сбрасывать со счетов и выполнение проверки таблиц при запуске
сервера. Например, всякий раз, когда во время обновления происходит
перезагрузка, необходима проверка всех таблиц, которые могли при этом
пострадать (назовем их "потенциально поврежденными таблицами"). В
safe_mysqld
можно добавить тест, запускающий myisamchk
для проверки всех
таблиц, измененных за последние 24 часа, в случае, если после перезагрузки
остался старый файл `.pid' (ID процесса) (mysqld
создает `.pid'-файл во время
запуска и удаляет его при нормальном завершении; наличие `.pid'-файла во
время запуска системы свидетельствует о том, что mysqld не завершился
нормально).
Можно сделать даже более надежный тест - выполнить проверку таблиц с более поздней, чем у `.pid'-файла, датой последней модификации.
Таблицы также следует регулярно проверять в ходе нормального
функционирования системы. У себя в MySQL AB
мы запускаем задачи по cron
для проверки всех наших важных таблиц раз в неделю, используя следующую
строку в файле crontab
:
35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI
Такая команда отображает информацию о поврежденных таблицах, и мы при надобности можем их исследовать и исправить.
Поскольку за последние пару лет у нас (на самом деле) не было неожиданно поврежденных таблиц (таблиц, получивших повреждение по причинам, отличным от неисправностей оборудования), то для нас проверки один раз в неделю более чем достаточно.
Мы рекомендуем для начала выполнять myisamchk -s
еженощно на всех
таблицах, обновленных на протяжении последних 24 часов, пока вы не станете
доверять MySQL настолько, насколько доверяем мы.
Обычно в таком контроле над таблицами MySQL необходимости нет. При
изменении таблиц с динамическим размером строк (таблиц со столбцами типов
VARCHAR
, BLOB
или TEXT
) или при наличии таблиц с большим числом удаленных
строк может потребоваться время от времени (где-то раз в месяц)
дефрагментировать таблицы.
Это можно сделать, используя OPTIMIZE TABLE
на аналогичных таблицах, или,
если есть возможность приостановить mysqld
, выполняя:
isamchk -r --silent --sort-index -O sort_buffer_size=16M */*.ISM myisamchk -r --silent --sort-index -O sort_buffer_size=16M */*.MYI
4.4.8 Получение информации о таблице
Команды, представленные в этом разделе, используются для получения описания таблицы или статистики по таблице. Более подробное выборочное разъяснение вывода этих команд будет приведено ниже:
- myisamchk -d tbl_name
Выполняет myisamchk в "описательном режиме" для
вывода описания таблицы. Если MySQL использует опцию
--skip-external-locking
, тоmyisamchk
может сообщить об ошибке для таблицы, обновляемой во время исполнения утилиты. Однако посколькуmyisamchk
не меняет таблицы в описательном режиме, то никакого риска разрушения данных нет. - myisamchk -d -v tbl_name
Для выдачи дополнительной информации по
действиям, выполняемым утилитой
myisamchk
, добавляется -v для указания расширенного режима вывода сообщений. - myisamchk -eis tbl_name Отображается только наиболее важная информация из таблицы. Работает медленно вследствие того, что приходится считывать всю таблицу.
- myisamchk -eiv tbl_name
То же, что и
-eis
, но с сообщением о выполняемых действиях.
Пример вывода myisamchk -d
:
MyISAM 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
:
MyISAM 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 Datafilepointer (bytes): 3 Keyfile pointer (bytes): 3 Max datafile length: 3791650815 Max keyfile length: 4294967294 Recordlength: 226 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 MyISAM 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 MyISAM 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: 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 [кое-что опущено для краткости] 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
Для использованной в предыдущих примерах таблицы размеры файла данных и индексного файла были следующими:
-rw-rw-r-- 1 monty tcx 317235748 Jan 12 17:30 company.MYD -rw-rw-r-- 1 davida tcx 96482304 Jan 12 18:35 company.MYM
Ниже приводятся пояснения по различным типам выдаваемой myisamchk
информации. ``keyfile'' означает индексный файл. ``Record'' (запись) и ``row''
(строка) являются синонимами:
- ISAM file - Имя (индексного) файла ISAM.
- Isam-version - Версия формата ISAM. На данный момент всегда 2.
- Creation time - Время создания файла данных.
- Recover time - Дата последнего восстановления индексного файла/файла данных.
- Data records - Количество записей в таблице.
- Deleted blocks - Количество удаленных блоков, пространство для которых все еще зарезервировано. Таблицу можно оптимизировать для сведения к минимуму этого пространства (see section 4.4.6.10 Оптимизация таблиц).
- Datafile parts - Для динамического формата записей показывает количество
блоков данных. Для оптимизированной таблицы без фрагментированных записей
совпадает с
Data records
. - Deleted data - Количество байтов удаленных данных, которые не были затребованы. Можно оптимизировать таблицу, чтобы сделать этот объем минимальным (see section 4.4.6.10 Оптимизация таблиц).
- Data file pointer - Размер указателя в файле данных (в байтах). Обычно это 2, 3, 4 или 5 байтов. Для большинства таблиц достаточно 2 байтов, но назначение размера пока невозможно контролировать из MySQL. Для фиксированных таблиц указатель - это адрес записи, а для динамических - адрес байта.
- Keyfile pointer - Размер указателя индексного файла в байтах. Обычно составляет 1, 2 или 3 байта. Для большинства таблиц хватает 2 байтов, но размер автоматически вычисляется MySQL. Указатель всегда является адресом блока.
- Max datafile length - Максимальный размер файла данных таблицы (`.MYD'-файл) в байтах.
- Max keyfile length - Максимальный размер индексного файла таблицы (`.MYI-файла') в байтах.
- Recordlength - Размер отдельной записи в байтах.
- Record format - Формат, используемый для хранения строк таблицы. В
примерах, приведенных выше, использовался формат
Fixed length
. Другие возможные значения:Compressed
иPacked
. - table description - Список всех ключей в таблице. Для каждого ключа
представляется некоторая низкоуровневая информация:
- Key Номер данного ключа.
- Start Место в записи, где начинается данная часть индекса.
- Len Длина данной части индекса. Для упакованных чисел длина всегда должна равняться полной длине для столбца. Для строк длина может быть меньше полной длины индексированной колонки, поскольку допускается индексирование префикса столбца со значениями строками.
- Индекс
unique
илиmultip
. (multiple - повторяющийся/многократный) Показывает, может ли одно значение встречаться в индексе многократно. - Type
Тип данных данной части индекса. Это тип данных
ISAM
с возможными вариантами -packed
,stripped
иempty
. - Root Адрес корневого индексного блока.
- Blocksize Размер каждого индексного блока. По умолчанию равен 1024, но значение можно изменить во время компиляции.
- Rec/key
Статистическое значение, используемое оптимизатором. Оно
показывает, сколько записей приходится на одно значение для данного ключа.
Для уникального ключа это соотношение всегда 1. Значение может быть
обновлено после загрузки таблицы (или значительного ее изменения)
посредством
myisamchk -a
. Если соотношение совсем не обновляется, то по умолчанию принимается значение 30.
- В первом из приведенных примеров 9-й ключ является составным с двумя частями.
- Keyblocks used - Процент использованных блоков ключей. Поскольку для
примера была взята таблица, совсем недавно реорганизованная при помощи
myisamchk
, то значения очень высоки (очень близки к теоретическому максимуму). - Packed - MySQL пытается упаковывать ключи с общим суффиксом. Это может
быть использовано только для ключей типа
CHAR
/VARCHAR
/DECIMAL
. Для длинных строк, таких как имена, при помощи упаковки можно значительно уменьшить занимаемое ими место. В третьем из приведенных примеров 4-й ключ состоит из 10 символов и для него достигнуто 60%-е уменьшение в объеме. - Max levels - Глубина B-дерева для данного ключа. В больших таблицах с длинными ключами значение является большим.
- Records Количество строк в таблице.
- M.recordlength - Средняя длина записи. Для таблиц с фиксированной длиной записи равняется точной длине записи.
- Packed - MySQL отбрасывает пробелы в конце строк. Значение
Packed
указывает на процент достигнутой этим экономии. - Recordspace used - Процент использования файла данных.
- Empty space - На сколько процентов файл данных не использован.
- Blocks/Record - Среднее число блоков на запись (т.е. из какого числа
связей состоит фрагментированная запись). Отношение всегда 1,0 для таблиц
фиксированного формата. Важно, чтобы это значение было как можно ближе к
1,0. Если значение становится слишком большим, можно реорганизовать
таблицу с помощью
myisamchk
. Обращайтесь к разделу See section 4.4.6.10 Оптимизация таблиц. - Recordblocks - Количество использованных блоков (связей). Для фиксированного формата совпадает с количеством записей.
- Deleteblocks - Количество удаленных блоков (связей).
- Recorddata - Количество использованных байтов в файле данных.
- Deleted data - Количество удаленных (неиспользуемых) байтов в файле данных.
- Lost space - Если запись при обновлении уменьшается, то теряется некоторое пространство. Данное значение является суммой всех таких потерь в байтах.
- Linkdata - При использовании динамического формата таблиц фрагменты
записи связываются с помощью указателей (каждый от 4 до 7 байтов).
Linkdata
- общий объем памяти, занимаемый всеми такими указателями.
Если таблица была сжата при помощи myisampack
, то myisamchk -d
выдает
дополнительную информацию о каждом столбце в таблице. Обращайтесь к
разделу See section 4.7.4 myisampack
, MySQL-генератор сжатых таблиц (только для чтения), где
приведен пример такой информации и пояснение к ней.
4.5 Справочник по языку администрирования баз данных
4.5.1 Синтаксис команды OPTIMIZE TABLE
OPTIMIZE TABLE tbl_name[,tbl_name]...
Команда OPTIMIZE TABLE
должна использоваться после удаления большей части
таблицы или если в таблице было внесено много изменений в строки
переменной длины (таблицы, в которых есть столбцы VARCHAR
, BLOB
или TEXT
).
Удаленные записи поддерживаются при помощи связного списка, и последующие
операции INSERT
повторно используют позиции старых записей. Чтобы
перераспределить неиспользуемое пространство и дефрагментировать файл
данных, можно воспользоваться командой OPTIMIZE TABLE
.
На данный момент команда OPTIMIZE TABLE
работает только с таблицами MyISAM
и BDB
. Для таблиц BDB
команда OPTIMIZE TABLE
выполняет ANALYZE TABLE
. См.
раздел See section 4.5.2 Синтаксис команды ANALYZE TABLE
.
Можно применить OPTIMIZE TABLE
к таблицам других типов, запустив
mysqld
с параметром --skip-new
или --safe-mode
, но в этом случае
OPTIMIZE TABLE
лишь только выполняет ALTER TABLE
.
Команда OPTIMIZE TABLE
работает следующим образом:
- Если в таблице есть удаленные или разделенные строки, восстанавливает таблицу.
- Если индексные страницы не отсортированы - сортирует их.
- Если статистические данные не обновлены (и восстановление нельзя осуществить путем сортировки индексов), обновляет их.
Команда OPTIMIZE TABLE
для MyISAM
представляет собой эквивалент
выполнения myisamchk --quick --check-only-changed --sort-index --analyze
над таблицей.
Обратите внимание: во время работы OPTIMIZE TABLE
таблица заблокирована!
4.5.2 Синтаксис команды ANALYZE TABLE
ANALYZE TABLE tbl_name[,tbl_name...]
Анализирует и сохраняет распределение ключей для таблицы. Во время
проведения анализа таблица заблокирована для чтения. Эта функция работает
для таблиц MyISAM
и BDB
.
Данная команда является эквивалентом выполнения myisamchk -a
для таблицы.
Сохраненное распределение ключей в MySQL используется для принятия решения о том, в каком порядке следует связывать таблицы, когда для связывания используются не константы, а другая база.
Эта команда выдает таблицу со следующими столбцами:
Столбец | Значение |
Table | Имя таблицы |
Op | Всегда ``analyze'' |
Msg_type | Одно из значений status , error , info или warning .
|
Msg_text | Сообщение. |
Просмотреть сохраненное распределение ключей можно при помощи команды SHOW
INDEX
. See section 4.5.6.1 Получение информации по базам данных, таблицам, столбцам и индексам.
Если таблица не изменялась с момента предыдущего запуска команды ANALYZE
TABLE
, повторный анализ таблицы проводиться не будет.
4.5.3 Синтаксис команды FLUSH
FLUSH flush_option [,flush_option] ...
Команда FLUSH
применяется для очистки части кэша, используемого MySQL. Для
запуска FLUSH
необходимо обладать привилегиями RELOAD
.
Параметр flush_option
может быть одним из следующих:
Параметр | Описание |
HOSTS | Производится очистка таблиц кэша удаленных компьютеров. Сброс таблиц удаленного компьютера следует производить, если один из удаленных компьютеров изменил IP-адрес или если было получено сообщение об ошибке Host ... is blocked . Если во время соединения с сервером MySQL происходит больше ошибок подряд, чем указано в max_connect_errors для определенного удаленного компьютера, то MySQL предполагает, что что-то не в порядке, и блокирует последующие попытки установления соединения со стороны этого удаленного компьютера. Сброс таблиц удаленного компьютера позволяет снова попытаться установить соединение. See section A.2.4 Ошибка Host '...' is blocked . Чтобы это сообщение об ошибке не появлялось, запустите mysqld с параметром -O max_connect_errors=999999999 .
|
DES_KEY_FILE | Производится перезагрузка ключей DES из файла, указанного параметром --des-key-file , при запуске сервера.
|
LOGS | Закрываются и повторно открывается все файлы журналов. Если файл журнала обновлений или файл бинарного журнала был указан без расширения, номер расширения файла журнала будет увеличен на единицу относительно предыдущего файла. Если в имени файла было указано расширение, MySQL закроет и повторно откроет файл журнала обновлений. See section 4.9.3 Журнал обновлений (update). Эти действия аналогичны отправке сигнала SIGHUP на сервер mysqld .
|
PRIVILEGES | Производится перезагрузка привилегий из таблиц привилегий в базе данных mysql .
|
QUERY CACHE | Производится дефрагментация кэша запросов, чтобы эффективнее использовать его память. Эта команда не удаляет запросы из кэша, как команда RESET QUERY CACHE .
|
TABLES | Закрываются все открытые таблицы и принудительно закрываются все используемые таблицы. Также сбрасывается кэш запросов. |
[TABLE | TABLES] tbl_name [,tbl_name...] | Производится сброс только указанных таблиц. |
TABLES WITH READ LOCK | Закрываются все открытые таблицы и блокируется доступ для чтения всех таблиц для всех баз данных, пока не будет запущена команда UNLOCK TABLES . Это очень удобный способ создавать резервные копии, если у вас файловая система наподобие Veritas, которая может обеспечить моментальные снимки данных в режиме реального времени.
|
STATUS | Большинство переменных состояния сбрасываются в нуль. Эту команду необходимо использовать при отладке запроса. |
USER_RESOURCES | Все ресурсы пользователя сбрасываются в нулевое значение. Это позволяет заблокированному пользователю подсоединиться еще раз. See section 4.3.6 Ограничение ресурсов пользователя. |
Ко всем приведенным выше командам можно получить доступ при помощи утилиты
mysqladmin
, используя команды flush-hosts
, flush-logs
, reload
или
flush-tables
.
Рекомендуется также ознакомиться с командой RESET
, которая применяется с
репликацией. See section 4.5.4 Синтаксис команды RESET
.
4.5.4 Синтаксис команды RESET
RESET reset_option [,reset_option] ...
Команда RESET
используется для очистки. Кроме того, она также действует
как более сильная версия команды FLUSH
. See section 4.5.3 Синтаксис команды FLUSH
.
Чтобы запустить команду RESET
, необходимо обладать привилегиями RELOAD
.
Параметр | Описание |
MASTER | Удаляет все бинарные журналы, перечисленные в индексном файле, обнуляет значения индексного файла binlog . В версиях до 3.23.26 - FLUSH MASTER (Master)
|
SLAVE | Сбрасывает положение репликации подчиненного компьютера в журналах головного компьютера. В версиях до 3.23.26 эта команда называлась FLUSH SLAVE (Slave)
|
QUERY CACHE | Удаляет все результаты запросов из кэша запросов. |
4.5.5 Синтаксис команды KILL
KILL thread_id
Каждое соединение с mysqld
запускается в отдельном потоке. При помощи
команды SHOW PROCESSLIST
можно просмотреть список запущенных потоков, а
при помощи команды KILL thread_id
- удалить поток.
Если у вас есть привилегия PROCESS
, можно просмотреть все потоки. Обладая
привилегией SUPER
, можно удалять любые потоки. В противном случае можно
просматривать и удалять только свои собственные потоки.
Для просмотра и удаления потоков можно также применять команды mysqladmin
processlist
и mysqladmin kill
.
При использовании команды KILL
для потока устанавливается специальный флаг
kill flag
.
В большинстве случаев удаление потока занимает некоторое время, поскольку этот флаг проверяется с определенным интервалом.
-
В циклах
SELECT
,ORDER BY
иGROUP BY
флаг проверяется только после считывания блока строк. Если установлен флаг удаления, то выполнение оператора будет отменено. -
При выполнении команды
ALTER TABLE
флаг удаления проверяется перед считыванием каждого блока строк из исходной таблицы. Если флаг установлен, то выполнение команды отменяется и временная таблица удаляется. При выполнении командUPDATE
иDELETE
флаг удаления проверяется после каждого считывания блока, а также после каждого обновления или удаления строки. Если флаг удаления установлен, то выполнение оператора отменяется. Обратите внимание: если не используются транзакции, то отменить изменения будет невозможно! -
GET_LOCK()
будет отменен при помощиNULL
. -
Поток
INSERT DELAYED
быстро сбросит все строки, которые он содержит в памяти и будет удален. -
Если поток находится в заблокированной таблице (состояние:
Locked
), то блокировка таблицы будет быстро отменена. - Если поток ожидает освобождения дискового пространства в запросе write, запись будет отменена с выдачей сообщения о переполнении диска.
4.5.6 Синтаксис команды SHOW
SHOW DATABASES [LIKE wild] или SHOW [OPEN] TABLES [FROM db_name] [LIKE wild] или SHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [LIKE wild] или SHOW INDEX FROM tbl_name [FROM db_name] или SHOW TABLE STATUS [FROM db_name] [LIKE wild] или SHOW STATUS [LIKE wild] или SHOW VARIABLES [LIKE wild] или SHOW LOGS или SHOW [FULL] PROCESSLIST или SHOW GRANTS FOR user или SHOW CREATE TABLE table_name или SHOW MASTER STATUS или SHOW MASTER LOGS или SHOW SLAVE STATUS или SHOW WARNINGS [LIMIT #] или SHOW ERRORS [LIMIT #] или SHOW TABLE TYPES
Команда SHOW
предоставляет информацию по базам данных, таблицам, столбцам
или о состоянии сервера. Если используется LIKE wild
, то строка wild
может
содержать в себе шаблонные символы SQL `%' и `_'.
4.5.6.1 Получение информации по базам данных, таблицам, столбцам и индексам
Можно использовать два альтернативных синтаксиса - tbl_name FROM db_name
и
db_name.tbl_name
. Приведенные ниже два оператора эквивалентны:
mysql> SHOW INDEX FROM mytable FROM mydb; mysql> SHOW INDEX FROM mydb.mytable;
Команда SHOW DATABASES
выдает список баз данных на компьютере, где
установлен сервер MySQL. Этот список можно также получить,
воспользовавшись инструментом командной строки mysqlshow
. В версии 4.0.2
можно увидеть только те базы данных, для которых у вас есть какие-либо
привилегии, если вы не имеете глобальной привилегии SHOW DATABASES
.
Команда SHOW TABLES
выводит список таблиц в указанной базе данных. Этот
список также можно получить, используя команду mysqlshow db_name
.
Примечание: если у пользователя нет никаких привилегий для таблицы,
таблица не будет показана в результатах команды SHOW TABLES
или mysqlshow
db_name
.
Команда SHOW OPEN TABLES
выводит список таблиц, которые в настоящий момент
открыты в кэше таблицы. See section 5.4.7 Открытие и закрытие таблиц в MySQL. В
поле Comment
указывается, сколько раз таблица кэшировалась (cached
) и
сколько раз использовалась (in_use
).
Команда SHOW COLUMNS
выводит список столбцов в заданной таблице. Если
указать параметр FULL
, то будут показаны также ваши привилегии для каждого
столбца. Если типы столбцов отличаются от заданных в параметрах оператора
CREATE TABLE
, учтите, что MySQL иногда изменяет типы столбцов. See section 6.5.3.1 Молчаливые изменения определений столбцов.
Оператор DESCRIBE
предоставляет почти такую же информацию, что и SHOW
COLUMNS
. See section 6.6.2 Синтаксис команды DESCRIBE
(Получение информации о столбцах).
Команда SHOW FIELDS
является синонимом команды SHOW COLUMNS
, а
команда SHOW KEYS
- синонимом SHOW INDEX
. Список столбцов или
индексов таблицы можно также вывести при помощи команды mysqlshow
db_name tbl_name
или mysqlshow -k db_name tbl_name
.
Команда SHOW INDEX
выводит информацию по индексу в формате, подобном
формату вывода запроса SQLStatistics в ODBC
. Выводятся следующие столбцы:
Столбец | Значение |
Table | Имя таблицы. |
Non_unique | 0 если индекс не может содержать дублирующихся значений. |
Key_name | Имя индекса. |
Seq_in_index | Порядковый номер столбца в индексе, начиная с 1. |
Column_name | Имя столбца. |
Collation | Как столбцы отсортированы в индексе. В MySQL в данном столбце могут присутствовать значения 'A' (в порядке возрастания) или NULL (не отсортирован).
|
Cardinality | Количество уникальных значений в индексе. Обновляется путем запуска isamchk -a .
|
Sub_part Количество индексированных символов, если столбец индексируется частично. Если проиндексирован весь ключ, то будет содержаться значение NULL .
| |
Null | Содержит значение 'YES' , если столбец может содержать NULL .
|
Index_type Используемый метод индексирования.
| |
Comment | Различные примечания. На данный момент в версиях MySQL < 4.0.2 выдается, является индекс FULLTEXT или нет.
|
Обратите внимание на то, что значение Cardinality
подсчитывается по
результатам статистики, сохраняющейся в виде целых чисел, которые
недостаточно точны для небольших таблиц.
Столбцы Null
и Index_type
были добавлены начиная с версии MySQL 4.0.2.
4.5.6.2 SHOW TABLE STATUS
SHOW TABLE STATUS [FROM db_name] [LIKE wild]
Команда SHOW TABLE STATUS
(новшество версии 3.23) работает как SHOW
STATUS
, но предоставляет большое количество информации по каждой таблице.
Приведенный ниже список также можно получить, используя команду mysqlshow
--status db_name
. Выводятся следующие столбцы:
Столбец | Значение |
Name | Имя таблицы. |
Type | Тип таблицы. See section 7 Типы таблиц MySQL. |
Row_format | Формат хранения строк (Fixed, Dynamic, или Compressed). |
Rows | Количество строк. |
Avg_row_length | Средняя длина строки. |
Data_length | Размер файла данных. |
Max_data_length | Максимальная длина файла данных. |
Index_length | Длина индексного файла. |
Data_free | Количество распределенных, но не используемых байтов. |
Auto_increment | Следующее значение автоинкремента. |
Create_time | Время создания таблицы. |
Update_time | Время последнего обновления файла данных. |
Check_time | Время последней проверки таблицы. |
Create_options | Дополнительные параметры, использовавшиеся для команды CREATE TABLE .
|
Comment | Примечания, внесенные при создании таблицы (или информация о причинах, почему MySQL не может получить доступ к данным в таблицах). |
В таблицах InnoDB
информация о свободном дисковом пространстве в таблице
заносится в ячейки примечаний к таблице.
4.5.6.3 SHOW STATUS
Команда SHOW STATUS
предоставляет информацию по состоянию сервера (как
mysqladmin extended-status
). Пример выходных данных приведен ниже (формат
и числа могут иметь некоторые отличия):
+--------------------------+------------+ | Variable_name | Value | +--------------------------+------------+ | Aborted_clients | 0 | | Aborted_connects | 0 | | Bytes_received | 155372598 | | Bytes_sent | 1176560426 | | Connections | 30023 | | Created_tmp_disk_tables | 0 | | Created_tmp_tables | 8340 | | Created_tmp_files | 60 | | Delayed_insert_threads | 0 | | Delayed_writes | 0 | | Delayed_errors | 0 | | Flush_commands | 1 | | Handler_delete | 462604 | | Handler_read_first | 105881 | | Handler_read_key | 27820558 | | Handler_read_next | 390681754 | | Handler_read_prev | 6022500 | | Handler_read_rnd | 30546748 | | Handler_read_rnd_next | 246216530 | | Handler_update | 16945404 | | Handler_write | 60356676 | | Key_blocks_used | 14955 | | Key_read_requests | 96854827 | | Key_reads | 162040 | | Key_write_requests | 7589728 | | Key_writes | 3813196 | | Max_used_connections | 0 | | Not_flushed_key_blocks | 0 | | Not_flushed_delayed_rows | 0 | | Open_tables | 1 | | Open_files | 2 | | Open_streams | 0 | | Opened_tables | 44600 | | Questions | 2026873 | | Select_full_join | 0 | | Select_full_range_join | 0 | | Select_range | 99646 | | Select_range_check | 0 | | Select_scan | 30802 | | Slave_running | OFF | | Slave_open_temp_tables | 0 | | 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_created | 30022 | | Threads_connected | 1 | | Threads_running | 1 | | Uptime | 80380 | +--------------------------+------------+
Приведенные выше переменные состояния имеют следующие значения:
Переменная | Значение |
Aborted_clients | Количество соединений, отмененных по причине отключения клиента без надлежащего закрытия соединения. See section A.2.9 Коммуникационные ошибки / Оборванные соединения. |
Aborted_connects | Количество неудачных попыток подсоединения к серверу MySQL. See section A.2.9 Коммуникационные ошибки / Оборванные соединения. |
Bytes_received | Количество байтов, полученных от всех клиентов. |
Bytes_sent | Количество байтов, отправленных всем клиентам. |
Com_xxx | Количество запусков каждой команды xxx. |
Connections | Количество попыток подсоединения к серверу MySQL. |
Created_tmp_tables | Количество неявных временных таблиц на диске, созданных во время выполнения операторов. |
Created_tmp_tables | Количество неявных временных таблиц в памяти, созданных во время выполнения операторов. |
Created_tmp_files | Количество созданных временных файлов mysqld .
|
Delayed_insert_threads | Количество используемых потоков вставки данных в режиме insert delayed .
|
Delayed_writes | Количество строк, вставленных при помощи команды INSERT DELAYED .
|
Delayed_errors | Количество записанных при помощи команды INSERT DELAYED строк, в которых произошли какие-либо ошибки (возможно, duplicate key ).
|
Flush_commands | Количество запущенных команд FLUSH .
|
Handler_commit | Количество внутренних команд COMMIT .
|
Handler_delete | Количество удалений строки из таблицы. |
Handler_read_first | Количество считываний из индекса первой записи. Если это значение высокое, то, по всей вероятности, сервер осуществляет много полных индексных сканирований, например, SELECT col1 FROM foo , предполагая, что col1 проиндексирован.
|
Handler_read_key | Количество запросов на чтение строки, основанных на ключе. Высокое значение переменной говорит о том, что ваши запросы и таблицы проиндексированы надлежащим образом. |
Handler_read_next | Количество запросов на чтение следующей строки в порядке расположения ключей. Это значение будет увеличиваться, если производится запрос индексного столбца с ограничением по размеру. Значение также увеличивается во время проведения индексного сканирования. |
Handler_read_prev | Количество запросов на чтение предыдущей строки в порядке расположения ключей. В большинстве случаев используется для оптимизации ORDER BY ... DESC .
|
Handler_read_rnd | Количество запросов на чтение строки, основанных на фиксированной позиции. Значение будет высоким, если выполняется много запросов, требующих сортировки результатов. |
Handler_read_rnd_next | Количество запросов на чтение следующей строки из файла данных. Данное значение будет высоким, если производится много сканирований таблиц. Обычно это означает, что ваши таблицы не проиндексированы надлежащим образом или ваши запросы не используют преимущества индексов. |
Handler_rollback | Количество внутренних команд ROLLBACK .
|
Handler_update | Количество запросов на обновление строки в таблице. |
Handler_write | Количество запросов на вставку строки в таблицу. |
Key_blocks_used | Количество используемых блоков в кэше ключей. |
Key_read_requests | Количество запросов на чтение блока ключей из кэша. |
Key_reads | Количество физических считываний блока ключей с диска. |
Key_write_requests | Количество запросов на запись блока ключей в кэш. |
Key_writes | Количество физических записей блоков ключей на диск. |
Max_used_connections | Максимальное количество одновременно используемых соединений. |
Not_flushed_key_blocks | Блоки ключей в кэше ключей, которые были изменены, но еще не записаны на диск. |
Not_flushed_delayed_rows | Количество строк, стоящих в очереди на запись в запросах INSERT DELAY .
|
Open_tables | Количество открытых таблиц. |
Open_files | Количество открытых файлов. |
Open_streams | Количество открытых потоков (в основном используется для журналирования). |
Opened_tables | Количество открывавшихся таблиц. |
Rpl_status | Статус отказобезопасной репликации (еще не используется). |
Select_full_join | Количество соединений без ключей (если это значение равно 0, необходимо внимательно проверить индексы своих таблиц). |
Select_full_range_join | Количество соединений, где был использован поиск по диапазону в справочной таблице. |
Select_range | Количество соединений, в которых использовались диапазоны в первой таблице. (Обычно это значение не критично, даже если оно велико) |
Select_scan | Количество соединений, в которых проводилось первое сканирование первой таблицы. |
Select_range_check | Количество соединений без ключей, в которых проверка использования ключей производится после каждой строки (если это значение равно 0, необходимо внимательно проверить индексы своих таблиц). |
Questions | Количество запросов, направленных на сервер. |
Slave_open_temp_tables | Количество временных таблиц, открытых в настоящий момент потоком подчиненного компьютера. |
Slave_running | Содержит значение ON , если это подчиненный компьютер, подключенный к головному компьютеру.
|
Slow_launch_threads | Количество потоков, создание которых заняло больше, чем указано в slow_launch_time .
|
Slow_queries | Количество запросов, обработка которых заняла больше времени, чем long_query_time . See section 4.9.5 Журнал медленных запросов.
|
Sort_merge_passes | Количество объединений, осуществленных алгоритмом сортировки. Если это значение велико, следует увеличить sort_buffer_size .
|
Sort_range | Количество сортировок, которые осуществлялись в диапазонах. |
Sort_rows | Количество отсортированных строк. |
Sort_scan | Количество сортировок, осуществленных путем сканирования таблицы. |
ssl_xxx | Переменные, используемые SSL; еще не реализовано. |
Table_locks_immediate | Количество запросов на немедленную блокировку таблицы. Доступно начиная с версии 3.23.33. |
Table_locks_waited | Количество запросов, когда немедленная блокировка не могла быть осуществлена и требовалось время на ожидание. Если это значение велико, и у вас есть проблемы с производительностью, сначала необходимо оптимизировать свои запросы, а затем либо разделить таблицы, либо использовать репликацию. Доступно начиная с версии 3.23.33. |
Threads_cached | Количество потоков в кэше потоков. |
Threads_connected | Количество открытых в настоящий момент соединений. |
Threads_created | Количество потоков, созданных для управления соединениями. |
Threads_running | Количество не простаивающих потоков. |
Uptime | Время в секундах, в течение которого сервер находится в работе. |
Некоторые примечания к приведенной выше информации:
-
Если значение
Opened_tables
велико, возможно, что значение переменнойtable_cache
слишком мало. -
Если значение
Key_reads
велико, возможно, что значение переменнойkey_buffer_size
слишком мало. Частоту неуспешных обращений к кэшу можно вычислить так:Key_reads
/Key_read_requests
. -
Если значение
Handler_read_rnd
велико, возможно, поступает слишком много запросов, требующих от MySQL полного сканирования таблиц или у вас есть соединения, которые не используют ключи надлежащим образом. -
Если значение
Threads_created
велико, возможно, необходимо увеличить значение переменнойthread_cache_size
. Частоту успешных обращений к кэшу можно вычислить при помощиThreads_created
/Connections
. -
Если значение
Created_tmp_disk_tables
велико, возможно, необходимо увеличить значение переменнойtmp_table_size
, чтобы временные таблицы располагались в памяти, а не на жестком диске.
4.5.6.4 SHOW VARIABLES
SHOW [GLOBAL | SESSION] VARIABLES [LIKE wild]
Команда SHOW VARIABLES
отображает значения некоторых системных переменных
MySQL. Такую же информацию можно получить и при помощи команды mysqladmin
variables
. Если установленные по умолчанию значения вам не подходят,
большинство из этих переменных можно задать, используя параметры командной
строки при запуске mysqld
. See section 4.1.1 Параметры командной строки mysqld
.
Опции GLOBAL
и SESSION
новы с версии MySQL 4.0.3. С помощью GLOBAL
вы получите
значения, использующиеся для новых подключений к MySQL. С помощью SESSION
вы
получите значения, которые действуют прямо сейчас в текущем соединении. Если вы
не указываете эти опции, подразумевается SESSION
.
Вы можете изменить большинство параметров с помощью команды SET
. See section 5.5.6 Синтаксис команды SET
.
Ниже приведен пример выходных данных; формат и числа могут иметь некоторые отличия:
+---------------------------------+------------------------------+ | Variable_name | Value | +---------------------------------+------------------------------| | back_log | 50 | | basedir | /usr/local/mysql | | bdb_cache_size | 8388572 | | bdb_log_buffer_size | 32768 | | bdb_home | /usr/local/mysql | | bdb_max_lock | 10000 | | bdb_logdir | | | bdb_shared_data | OFF | | bdb_tmpdir | /tmp/ | | bdb_version | Sleepycat Software: ... | | binlog_cache_size | 32768 | | bulk_insert_buffer_size | 8388608 | | character_set | latin1 | | character_sets | latin1 big5 czech euc_kr | | concurrent_insert | ON | | connect_timeout | 5 | | convert_character_set | | | datadir | /usr/local/mysql/data/ | | delay_key_write | ON | | delayed_insert_limit | 100 | | delayed_insert_timeout | 300 | | delayed_queue_size | 1000 | | flush | OFF | | flush_time | 0 | | ft_boolean_syntax | + -><()~*:""&| | | ft_min_word_len | 4 | | ft_max_word_len | 254 | | ft_max_word_len_for_sort | 20 | | ft_stopword_file | (built-in) | | have_bdb | YES | | have_innodb | YES | | have_isam | YES | | have_raid | NO | | have_symlink | DISABLED | | have_openssl | YES | | have_query_cache | YES | | init_file | | | innodb_additional_mem_pool_size | 1048576 | | innodb_buffer_pool_size | 8388608 | | innodb_data_file_path | ibdata1:10M:autoextend | | innodb_data_home_dir | | | innodb_file_io_threads | 4 | | innodb_force_recovery | 0 | | innodb_thread_concurrency | 8 | | innodb_flush_log_at_trx_commit | 0 | | innodb_fast_shutdown | ON | | innodb_flush_method | | | innodb_lock_wait_timeout | 50 | | innodb_log_arch_dir | | | innodb_log_archive | OFF | | innodb_log_buffer_size | 1048576 | | innodb_log_file_size | 5242880 | | innodb_log_files_in_group | 2 | | innodb_log_group_home_dir | ./ | | innodb_mirrored_log_groups | 1 | | interactive_timeout | 28800 | | join_buffer_size | 131072 | | key_buffer_size | 16773120 | | language | /usr/local/mysql/share/... | | large_files_support | ON | | local_infile | ON | | locked_in_memory | OFF | | log | OFF | | log_update | OFF | | log_bin | OFF | | log_slave_updates | OFF | | log_slow_queries | OFF | | log_warnings | OFF | | long_query_time | 10 | | low_priority_updates | OFF | | lower_case_table_names | OFF | | max_allowed_packet | 1047552 | | max_binlog_cache_size | 4294967295 | | max_binlog_size | 1073741824 | | max_connections | 100 | | max_connect_errors | 10 | | max_delayed_threads | 20 | | max_heap_table_size | 16777216 | | max_join_size | 4294967295 | | max_sort_length | 1024 | | max_user_connections | 0 | | max_tmp_tables | 32 | | max_write_lock_count | 4294967295 | | myisam_max_extra_sort_file_size | 268435456 | | myisam_max_sort_file_size | 2147483647 | | myisam_recover_options | force | | myisam_sort_buffer_size | 8388608 | | net_buffer_length | 16384 | | net_read_timeout | 30 | | net_retry_count | 10 | | net_write_timeout | 60 | | open_files_limit | 0 | | pid_file | /usr/local/mysql/name.pid | | port | 3306 | | protocol_version | 10 | | read_buffer_size | 131072 | | read_rnd_buffer_size | 262144 | | rpl_recovery_rank | 0 | | query_cache_limit | 1048576 | | query_cache_size | 0 | | query_cache_type | ON | | safe_show_database | OFF | | server_id | 0 | | slave_net_timeout | 3600 | | skip_external_locking | ON | | skip_networking | OFF | | skip_show_database | OFF | | slow_launch_time | 2 | | socket | /tmp/mysql.sock | | sort_buffer_size | 2097116 | | sql_mode | 0 | | table_cache | 64 | | table_type | MYISAM | | thread_cache_size | 3 | | thread_stack | 131072 | | tx_isolation | READ-COMMITTED | | timezone | EEST | | tmp_table_size | 33554432 | | tmpdir | /tmp/:/mnt/hd2/tmp/ | | version | 4.0.4-beta | | wait_timeout | 28800 | +---------------------------------+------------------------------+
Ниже описаны все параметры. Значения размеров буферов, длины и размеры
стеков приведены в байтах. Значения можно указать с суффиксом 'K'
или 'M'
,
чтобы обозначить килобайты или мегабайты. Например, 16M
означает 16
мегабайт. Регистр буквы суффикса не имеет значения, 16M
и 16m
обозначают
одно и то же:
ansi_mode
. Имеет значениеON
, еслиmysqld
был запущен с параметром--ansi
. See section 1.9.2 Запуск MySQL в режиме ANSI.back_log
Количество поддерживаемых MySQL запросов на соединение, находящихся в очереди. Этот параметр начинает играть роль, когда главный поток MySQL получает очень много запросов на соединение за короткий промежуток времени. У главного потока уходит некоторое время (хотя очень небольшое) на проверку соединения и запуск нового потока. Значениеback_log
показывает, сколько запросов может находиться в очереди на этом коротком промежутке времени, прежде чем MySQL прекратит отвечать на новые запросы. Данное значение необходимо увеличить только в том случае, если ожидается большое количество соединений на протяжении короткого промежутка времени. Иначе говоря, это значение является размером очереди ожидания входящих соединений TCP/IP. У вашей операционной системы есть свое собственное ограничение на размер этой очереди. За более подробной информацией обращайтесь на страницу руководства ОС Unix по системному вызовуlisten(2)
. Чтобы узнать максимальное значение для этой переменной, обратитесь к документации по своей операционной системе. Попытка установить значениеback_log
выше, чем допускается в вашей операционной системе, не принесет положительного результата.basedir
Значение параметра--basedir
.bdb_cache_size
Буфер, выделенный для индекса кэша и строк таблицBDB
. Если таблицыBDB
не используются, необходимо запуститьmysqld
с параметром--skip-bdb
, чтобы не расходовать память на этот кэш.bdb_log_buffer_size
Буфер, выделенный для индекса кэша и строк таблицBDB
. Если таблицыBDB
не используются, его значение необходимо установить в 0 или запуститьmysqld
с параметром--skip-bdb
, чтобы не расходовать память на этот кэш.bdb_home
Значение параметра--bdb-home
.bdb_max_lock
Максимальное количество блокировок (по умолчанию 10000), которые можно установить на таблицуBDB
. Этот параметр необходимо увеличить, если возникают ошибки типаbdb: Lock table is out of available locks
илиGot error 12 from ...
при выполнении длинных транзакций или когдаmysqld
должен просмотреть много строк для вычисления запроса.bdb_logdir
Значение параметра--bdb-logdir
.bdb_shared_data
Содержит значениеON
, если используется параметр--bdb-shared-data
.bdb_tmpdir
Значение параметра--bdb-tmpdir
.binlog_cache_size
. Размер кэша для хранения операторов бинарного журнала SQL во время транзакции. Если часто используются большие транзакции со значительным количеством операторов, то в целях повышения производительности значение этого параметра можно увеличить. See section 6.7.1 Синтаксис командBEGIN/COMMIT/ROLLBACK
.bulk_insert_buffer_size
(былmyisam_bulk_insert_tree_size
) MyISAM использует специальный древо-подобный кэш чтобы ускорить многострочные вставки (которыеINSERT ... SELECT
,INSERT ... VALUES (...), (...), ...
, иLOAD DATA INFILE
). Эта переменная ограничивает размер такого кэша в каждом потоке (указывается в байтах). Установка в 0 запретит такую оптимизацию.Внимание:
этот кэш работает только тогда, когда делается вставка в непустую таблицу. Значение по умолчанию: 8 Мб.character_set
Принятый по умолчанию набор символов.character_sets
Поддерживаемые наборы символов.concurrent_inserts
Если установлено значениеON
(принятое по умолчанию), MySQL обеспечивает возможность использовать командуINSERT
на таблицахMyISAM
одновременно с выполнением над этими же таблицами запросовSELECT
. Этот параметр можно отключить, запустивmysqld
с параметром--safe
или--skip-new
.connect_timeout
Количество времени в секундах, на протяжении которого серверmysqld
ожидает поступления пакета соединения, после чего генерируетBad handshake
.datadir
Значение параметра--datadir
.delay_key_write
Опция для таблиц MyISAM. Может принимать одно из следующих значений:
ЕслиOFF Все CREATE TABLE ... DELAYED_KEY_WRITES игнорируются. ON (по умолчанию) MySQL будет учитывать опцию DELAY_KEY_WRITE
вCREATE TABLE
.ALL Все вновь открытые таблицы обслуживаются так, будто бы они были созданы с опцией DELAY_KEY_WRITE
.DELAY_KEY_WRITE
включен, это означает что ключевой буфер для таблиц с этой опцией не будет сбрасываться на диск при каждом обновлении индексов, но только тогда, когда таблица закрывается. Это весьма ускорит записи ключей, но вы должны обязательно реализовать автоматическую проверку всех таких таблиц с помощьюmyisamchk --fast --force
если вы хотите использовать эту опцию.delay_key_write
Если включен (по умолчанию - включен), MySQL будет учитывать параметрDELAY_KEY_WRITE
для командыCREATE
TABLE. Это означает, что ключевой буфер таблиц с данным параметром будет сбрасываться на диск не при каждом обновлении индексов, а только при закрытии таблицы. Такой режим работы значительно ускоряет запись ключей, однако в случае использования данного параметра необходимо будет также добавить автоматическую проверку всех таблиц при помощиmyisamchk --fast --force
. Обратите внимание: если запуститьmysqld
с параметром--delay-key-write-for-all-tables
, то все таблицы будут обрабатываться таким образом, как будто они были созданы с применением параметраdelay_key_write
. Этот флаг можно снять, запустивmysqld
с параметром--skip-new
или--safe-mode
.delayed_insert_limit
После вставки строкdelayed_insert_limit
обработчикINSERT DELAYED
проверит, остались ли незавершенные операторыSELECT
. Если да, то перед тем, как приступить к выполнению следующих действий, они будут выполнены.delayed_insert_timeout
Временной промежуток, в течение которого процессINSERT DELAYED
должен ожидать операторовINSERT
до прекращения выполнения задачи.delayed_queue_size
Размер очереди (в строках), который должен быть назначен для обработки командыINSERT DELAYED
. При переполнении очереди все клиенты, выполняющие командуINSERT DELAYED
, будут ожидать, пока в очереди снова появится свободное место.flush
Значение этой переменной будетON
, если вы запустили MySQL с параметром--flush
.flush_time
Если значение этой переменной отличается от нуля, то каждыеflush_time
секунд все таблицы будут закрываться (чтобы освободить ресурсы и записать информацию на диск). Мы рекомендуем использовать этот параметр только для Windows 9x/Me или на системах с ограниченным количеством ресурсов.ft_boolean_syntax
Список операторов, поддерживаемыхMATCH ... AGAINST(... IN BOOLEAN MODE)
. See section 6.8 Полнотекстовый поиск в MySQL.ft_min_word_len
Минимальная длина слова, включаемого в индексFULLTEXT
. Примечание: индексыFULLTEXT
после изменения этой переменной должны быть скомпонованы заново (это новый параметр в MySQL 4.0).ft_max_word_len
Максимальная длина слова, включаемого в индексFULLTEXT
. Примечание: индексыFULLTEXT
после изменения этой переменной должны быть скомпонованы заново (это новый параметр в MySQL 4.0).ft_max_word_len_for_sort
Максимальная длина слова в индексеFULLTEXT
; эта длина будет использоваться для метода быстрого восстановления индекса в командахREPAIR
,CREATE INDEX
илиALTER
TABLE. Более длинные слова вставляются дольше. При увеличении значенияft_max_word_len_for_sort
MySQL будет создавать временные файлы большего размера (таким образом будет замедляться работа из-за возрастания нагрузки на порт ввода/вывода диска), а также будет помещать меньше ключей в один блок сортировки (что, опять же, способствует снижению производительности). Если значение переменнойft_max_word_len_for_sort
слишком мало, MySQL будет вставлять большое количество слов достаточно медленно, но короткие слова будут вставляться очень быстро.ft_stopword_file
Из этого файла читается список стоп-слов для полнотекстового поиска. Все слова из этого файла будут использованы, комментарии в этом файле недопустимы. По умолчанию используется встроенный список стоп-слов (определен в файле `myisam/ft_static.c'). Установка этого параметра в пустое значение (""
) выключает фильтрацию по стоп-словам. Внимание:FULLTEXT
индексы должны быть перестроены после того, как эта переменная изменена. (Эта опция нова в MySQL 4.0.10)have_innodb
ЗначениеYES
, еслиmysqld
поддерживает таблицыInnoDB
. ЗначениеDISABLED
, если используется параметр--skip-innodb
.have_bdb
ЗначениеYES
, еслиmysqld
поддерживает таблицыBerkeley DB
. ЗначениеDISABLED
, если используется параметр--skip-bdb
.have_raid
ЗначениеYES
, еслиmysqld
поддерживает параметрRAID
.have_openssl
ЗначениеYES
, еслиmysqld
поддерживает SSL (шифрование) в протоколе клиент/сервер.init_file
Имя файла, указанного при помощи параметра--init-file
при запуске сервера. Это файл операторов SQL, которые сервер должен выполнить при запуске.interactive_timeout
Количество времени в секундах, на протяжении которого сервер ожидает активности со стороны интерактивного соединения, прежде чем закрыть его. Интерактивный клиент - это клиент, который использует параметрCLIENT_INTERACTIVE
дляmysql_real_connect
(). См. также информацию поwait_timeout
.join_buffer_size
Размер буфера, используемого для полных объединений (объединения, в которых не применяются индексы). Буфер выделяется один раз для каждого полного объединения двух таблиц. Если нужно ускорить полное объединение и невозможно добавить индексы, следует увеличить это значение (обычно добавление индексов является лучшим способом добиться быстрых объединений).key_buffer_size
Блоки индексов буферизированы и доступ к ним разрешен всем потокам.key_buffer_size
- размер буфера, используемого для блоков индексов. Чтобы улучшить обработку индексов (для всех операций чтения и записи нескольких элементов), необходимо увеличить это значение настолько, насколько возможно. Размер 64 Мб для компьютера с 256 Мб (именно такой компьютер в основном используется для работы с MySQL) - довольно распространенная конфигурация. Тем не менее, если задать слишком большое значение (например, больше 50% от общего количества памяти), система может начать сохранять временные файлы на диске, что значительно снизит производительность. Помните, что, поскольку MySQL не производит кэширования считываемых данных, нужно оставлять определенное пространство для кэша файловой системы операционной системы. Производительность буфера ключей можно проверить, выполнив командуSHOW STATUS
и проверив значения переменныхKey_read_requests
,Key_reads
,Key_write_requests
иKey_writes
. Отношение значенийKey_reads
/Key_read_request
обычно должно быть < 0,01. ОтношениеKey_write
/Key_write_requests
примерно равно 1, если в основном используются обновления/удаления, но может быть и меньше, если чаще используются обновления сразу многих элементов или еслиDELAY_KEY_WRITE
. See section 4.5.6 Синтаксис командыSHOW
. Чтобы еще больше увеличить скорость при одновременной записи большого количества строк, используйте командуLOCK TABLES
. See section 6.7.2 Синтаксис командLOCK TABLES/UNLOCK TABLES
.language
Язык, используемый для вывода сообщений об ошибках.large_file_support
Еслиmysqld
был откомпилирован с параметрами для поддержки больших файлов.locked_in_memory
Еслиmysqld
был заблокирован в памяти при помощи--memlock
log
Если включено занесение в журнал всех запросов.log_update
Если включен журнал обновлений.log_bin
Если включен бинарный журнал.log_slave_updates
Если обновления от подчиненного компьютера должны заноситься в журнал.long_query_time
Если обработка запроса отнимает больше указанного промежутка времени (в секундах), значение счетчикаSlow_queries
будет увеличено. Если используется параметр--log-slow-queries
, запрос будет записан в журнал медленных запросов. Это значение указывается в единицах реального времени, а не времени занятости процессора (CPU time). Таким образом, некий запрос, который выполняется быстрее указываемого времени на слегка загруженном сервере может выполняться больше указанного времени на более загруженном компьютере. See section 4.9.5 Журнал медленных запросов.lower_case_table_names
Если установлено значение 1, имена таблиц будут сохранятся на диск с использованием строчных букв, а имена таблиц не будут чувствительны к регистру. С версии MySQL 4.0.2 это также касается и имен баз данных. See section 6.1.3 Чувствительность имен к регистру.max_allowed_packet
Максимальный размер одного пакета. Изначально размер буфера сообщений устанавливается вnet_buffer_length
байтов, но при необходимости может возрасти доmax_allowed_packet
байтов. Это значение по умолчанию не настолько велико, чтобы отсеивать большие (возможно ошибочные) пакеты. Если используются большие столбцыBLOB
, его необходимо увеличить. Значение должно быть не меньше самого большогоBLOB
, который будет использоваться. Ограничение протокола дляmax_allowed_packet
составляет 16 Мб в MySQL 3.23 и 1Гб в MySQL 4.0.max_binlog_cache_size
Если для транзакции с большим количеством операторов потребуется большее количество памяти, чем указано этим параметром, будет выдано сообщение об ошибке "Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage" (для транзакции с большим количеством операторов требуется больше, чем 'max_binlog_cache_size' байтов для хранения).max_binlog_size
Доступно после версии 3.23.33. Если запись в бинарный журнал (репликация) превысит данное значение, производится ротация журнала. Нельзя установить значение, меньшее, чем 1024 байта или большее, чем 1 Гб. По умолчанию установлено значение 1 Гб.max_connections
Разрешенное количество одновременно подсоединенных клиентов. Увеличение этого значения увеличивает количество дескрипторов файлов, необходимых дляmysqld
. Ниже приведены примечания по ограничениям для дескрипторов. See section A.2.5 ОшибкаToo many connections
.max_connect_errors
Если количество прерванных соединений с удаленным компьютером превышает это число, дальнейшие попытки удаленного компьютера установить соединение будут заблокированы. Блокировку с удаленного компьютера можно снять при помощи командыFLUSH HOSTS
.max_delayed_threads
Не запускайте больше потоков, чем указано здесь, для обработки операторовINSERT DELAYED
. Если попытаться вставить данные в новую таблицу, когда все потокиINSERT DELAYED
заняты, строка будет вставлена таким образом, как будто атрибутDELAYED
не был указан.max_heap_table_size
Не позволяет создавать динамические таблицы, размер которых превышает указанное значение.max_join_size
Объединения, которые потенциально могут считывать болееmax_join_size
записей, будут возвращать ошибку. Это значение нужно задавать, если ваши пользователи осуществляют объединения, которым недостает оператораWHERE
, - такие объединения занимают много времени, а затем возвращают миллионы строк.max_sort_length
Параметр определяет, сколько байтов следует использовать при сортировке значенийBLOB
илиTEXT
(обрабатываются только первыеmax_sort_length
байтов каждого значения, остальные игнорируются).max_user_connections
Максимальное количество активных соединений для одного пользователя (0 = без ограничений).max_tmp_tables
(Этот параметр пока ни на что не влияет.) Максимальное количество временных таблиц, которые клиент может открывать одновременно.max_write_lock_count
После данного количества блокирования записей разрешается выполнить между ними несколько блокировок чтения.myisam_recover_options
Значение параметра--myisam-recover
.myisam_sort_buffer_size
Буфер, который выделяется для сортировки индексов при выполнении командыREPAIR
или для создания индексов при помощи командCREATE INDEX
илиALTER TABLE
.myisam_max_extra_sort_file_size
. Если размер временного файла, используемого для быстрого создания индексов, превышает на указанный здесь объем используемый кэш ключей, то лучше отдать предпочтение методу кэша ключей. Такой метод применяется для того, чтобы для больших ключей символов в больших таблицах использовался более медленный метод кэширования ключей при создании таблиц. Обратите внимание: значение этого параметра в байтах, начиная с 4.0.3 (до 4.0.3 параметр указывался в мегабайтах).myisam_max_sort_file_size
Максимальный размер временного файла, который в MySQL может использоваться при восстановлении индекса (во время работы командREPAIR
,ALTER TABLE
илиLOAD DATA INFILE
). Для файлов, размер которых превышает указанное значение, индекс будет создаваться при помощи кэша ключей (такой алгоритм работает несколько медленнее). Обратите внимание: значение этого параметра в байтах, начиная с 4.0.3 (до 4.0.3 параметр указывался в мегабайтах).net_buffer_length
В данное значение устанавливается в промежутках между запросами буфер соединения. Обычно это значение не изменяется, но если у вас очень мало памяти, можно установить его по размеру ожидаемого запроса (т.е. равным предполагаемой длине операторов SQL, отправляемых клиентами; если оператор превысит указанную длину, буфер будет автоматически увеличен как максимум доmax_allowed_packet
байтов).net_read_timeout
Количество времени в секундах, на протяжении которого ожидаются дополнительные данные от соединения, пока не будет отменено чтение. Обратите внимание, что мы не ожидаем поступления данных от соединения, время ожидания определяется поwrite_timeout
. Также см.slave_net_timeout
.net_retry_count
Если чтение из порта связи было прервано, будет предпринято указанное количество попыток повторного чтения. Это значение должно быть достаточно высоким наFreeBSD
, так как внутренние прерывания направляются на все потоки.net_write_timeout
Время ожидания записи блока через соединение, пока запись не будет прервана (в секундах).open_files_limit
Если это значение отлично от 0, тоmysqld
будет применять его для резервных дескрипторов файлов, используемых сsetrlimit()
. Если это значение равно 0, тоmysqld
будет резервироватьmax_connections*5
илиmax_connections + table_cache*2
(в зависимости от того, какое число больше) файлов. Еслиmysqld
выдает ошибку 'Too many open files' (слишком много открытых файлов), данное значение необходимо увеличить.pid_file
Значение параметра--pid-file
.port
Значение параметра--port
.protocol_version
Версия протокола, используемого сервером MySQL.read_buffer_size
(былоrecord_buffer
) Каждый поток, осуществляющий последовательное сканирование, выделяет буфер указанного размера для каждой сканируемой таблицы. Если проводится много последовательных сканирований, это значение можно увеличить.record_rnd_buffer_size
При считывании строк после проведения сортировки в отсортированном порядке строки считываются через буфер, чтобы избежать операций поиска по диску. Это может улучшить выполнениеORDER BY
весьма и весьма, если параметр установлен в большое значение. Т.к. эта переменная имеет отношение к потоку, то не устанавливайте слишком большое значение глобально, но просто меняйте его при выполнении некоторых больших запросов.query_cache_limit
Результаты, превышающие это значение, не кэшируются (по умолчанию - 1Мб).query_cache_size
Память, выделенная для хранения результатов старых запросов. Если значение установлено в 0, кэш запросов отключен (принято по умолчанию).query_cache_type
Могут быть заданы следующие значения (только числовые):Значение Объяснение Примечание 0 OFF Не кэширует и не извлекает результаты. 1 ON Кэширует все результаты, кроме запросов SELECT SQL_NO_CACHE ...
.2 DEMAND Кэширует только запросы SELECT SQL_CACHE ...
.safe_show_database
Не отображаются базы данных, для которых у пользователя нет каких-либо привилегий по базам данных или таблицам. Таким образом можно увеличить степень безопасности, если вы не хотите предоставлять посторонним лицам возможность получать информацию о том, какие базы данных есть у других пользователей. Также см.skip_show_database
.server_id
Значение параметра--server-id
.skip_locking
Установлено в значениеOFF
, еслиmysqld
использует внешнюю блокировку.skip_networking
Установлено в значениеON
, если разрешаются только локальные соединения (через сокет).skip_show_database
Эта переменная не позволяет выполнять командуSHOW DATABASES
, если у пользователя нет привилегииPROCESS
. Таким образом можно увеличить степень безопасности, если вы не хотите предоставлять посторонним лицам возможность получать информацию о том, какие базы данных есть у других пользователей. Также см.safe_show_database
.slave_net_timeout
Количество времени в секундах, в течение которого ожидаются дополнительные данные от подсоединенного головного или подчиненного компьютера прежде, чем будет отменено чтение.slow_launch_time
Если создание потока занимает больше, чем указанное значение (в секундах), значение счетчикаSlow_launch_threads
будет увеличено.socket
Сокет Unix, используемый сервером.sort_buffer_size
Каждый поток, которому необходимо произвести сортировку, выделяет буфер данного размера. Увеличение данного значения позволит ускорить выполнение операторовORDER BY
илиGROUP BY
. See section A.4.4 Где MySQL хранит временные файлы.table_cache
Количество открытых таблиц для всех потоков. С увеличением этого значения увеличивается количество дескрипторов файлов, необходимых дляmysqld
. Чтобы узнать, необходимо ли изменять значение кэша таблиц, следует проверить значение переменнойOpened_tables
. См. раздел See section A.4.4 Где MySQL хранит временные файлы. Если у этой переменной большое значение, а командаFLUSH TABLES
(которая закрывает все таблицы, а потом открывает их повторно) используется не часто, то необходимо увеличить ее значение. Чтобы получить дополнительную информацию по кэшу таблиц, см. раздел See section 5.4.7 Открытие и закрытие таблиц в MySQL.table_type
Принятый по умолчанию тип таблиц.thread_cache_size
Определяет, сколько потоков должно сохраняться в кэше для повторного использования. После отключения клиента потоки клиента помещаются в кэш, если там не больше потоков, чемthread_cache_size
. Все новые потоки сначала берутся из кэша, и только когда кэш становится пустым, создаются новые потоки. Значение этой переменной можно увеличить, чтобы повысить производительность, если создается много новых соединений (если потоки у вас хорошо организованы, обычно заметного улучшения производительности не наблюдается). Насколько эффективен текущий кэш потоков, можно определить по разнице междуConnections
иThreads_created
.thread_concurrency
В системе Solarismysqld
вызывает функциюthr_setconcurrency()
с этим значением.thr_setconcurrency()
позволяет приложению дать системе потоков подсказку по необходимому количеству потоков, которые должны быть запущены в одно и то же время.thread_stack
Размер стека для каждого потока. От данного значения зависит большое количество ограничений, обнаруживаемых при помощи тестаcrash
-me. По умолчанию этот размер достаточен для нормальной работы. See section 5.1.4 Набор тестов MySQL (The MySQL Benchmark Suite).timezone
Часовой пояс, в котором находится сервер.tmp_table_size
Если находящаяся в памяти временная таблица превысит этот размер, MySQL автоматически преобразует ее в дисковую таблицуMyISAM
. Значениеtmp_table_size
следует увеличить, если выполняется много расширенных запросовGROUP BY
и в вашей системе установлено значительное количество оперативной памяти.tmpdir
Каталог, используемый для временных файлов и временных таблиц. Начиная с MySQL 4.1, вtmpdir
могут быть указаны несколько путей, разделенных двоеточием:
(точкой с запятой на Windows;
). Эти пути будут использованы в ротации.version
Номер версии сервера.wait_timeout
Время в секундах, на протяжении которого сервер наблюдает неактивность в неинтерактивном соединения прежде, чем закрыть его. Когда запускается поток,SESSION.WAIT_TIMEOUT
инициализируется исходя изGLOBAL.WAIT_TIMEOUT
илиGLOBAL.INTERACTIVE_TIMEOUT
, в зависимости от типа клиента (как определяется вCLIENT_INTERACTIVE
опции соединения). См. такжеinteractive_timeout
.
Раздел руководства, в котором описывается настройка MySQL содержит некоторую информацию по настройке приведенных выше переменных. See section 5.5.2 Настройка параметров сервера.
4.5.6.5 SHOW LOGS
SHOW LOGS
отображает информацию по состоянию существующих файлов журналов.
На данный момент выводится информация только по файлам журналов Berkeley
DB.
File
отображает полный путь к файлу журналаType
отображает тип файла журнала (BDB
для файлов журналов Berkeley DB)Status
отображает состояние файла журнала (FREE
- если файл может быть удален, илиIN USE
, если файл необходим подсистеме транзакций).
4.5.6.6 SHOW PROCESSLIST
Команда SHOW [FULL] PROCESSLIST
показывает, какие потоки запущены в
настоящий момент. Эту информацию также можно получить при помощи команды
mysqladmin processlist
. Если у вас привилегия SUPER
, можно
просматривать все потоки, в противном случае - только свои потоки. See section 4.5.5 Синтаксис команды KILL
.
Если не используется параметр FULL
, будут показаны только первые 100
символов каждого запроса.
Начиная с 4.0.12, MySQL сообщает имя хоста для TCP/IP соединений как
имя_хоста:клиентский_порт
с тем, чтобы было проще понять, какой клиент
чем занят.
Эта команда очень полезна, если выдается сообщение об ошибке 'too many
connections' (слишком много соединений) и необходимо выяснить, что
происходит. MySQL резервирует одно дополнительное соединение для клиента с
привилегией SUPER
, чтобы у вас всегда была возможность войти в систему и
произвести проверку (предполагается, что вы не станете раздавать эту
привилегию всем своим пользователям).
Некоторые состояния обычно можно увидеть в mysqladmin processlist
.
Checking table
Поток осуществляет [автоматическую] проверку таблицы.Closing tables
Означает, что поток записывает измененные данные таблиц на диск и закрывает использующиеся таблицы. Выполнение этой операции должно произойти быстро. Если на нее уходит значительное время, убедитесь, что диск не переполнен или что диск не используется слишком интенсивно.Connect Out
Подчиненный компьютер, подсоединенный к головному компьютеру.Copying to tmp table on disk
Набор временных результатов превысилtmp_table_size
, и теперь поток изменяет таблицу временных данных, расположенную в памяти, на дисковую таблицу, чтобы сохранить память.Creating tmp table
Поток создает временную таблицу, чтобы хранить часть результатов для запроса.deleting from main table
При запуске первой части удаления нескольких таблиц удаление производится только начиная с первой таблицы.deleting from reference tables
При запуске второй части удаления нескольких таблиц удаляются совпадающие строки из других таблиц.Flushing tables
Поток запускает командуFLUSH TABLES
и ожидает, пока все потоки закроют свои таблицы.Killed
Кто-то направил команду на закрытие потока, и поток будет закрыт при следующей проверке флага закрытия. Флаг проверяется при каждом основном цикле в MySQL, но в некоторых случаях закрытие потока может занять некоторое время. Если поток заблокирован другим потоком, закрытие будет произведено сразу после того, как другой поток снимет блокировку.Sending data
Поток обрабатывает строки для оператораSELECT
, а также направляет данные клиенту.Sorting for group
Поток осуществляет сортировку в соответствии сGROUP BY
.Sorting for order
Поток осуществляет сортировку в соответствии сORDER BY
.Opening tables
Это просто означает, что поток пытается открыть таблицу. Такая процедура осуществляется довольно быстро, если что-либо не мешает открытию. Например, командыALTER TABLE
илиLOCK TABLE
могут помешать открытию таблицы, пока выполнение команды не будет завершено.Removing duplicates
Запрос использовал командуSELECT DISTINCT
таким образом, что MySQL не смог произвести оптимизацию на начальном этапе. Поэтому MySQL перед отправкой результатов клиенту должен выполнить дополнительное удаление всех дублирующихся строк.Reopen table
Поток заблокировал таблицу, но обнаружил, что после блокировки структура таблицы изменилась. Он снял блокировку, закрыл таблицу и теперь пытается повторно ее открыть.Repair by sorting
Код восстановления использует сортировку для создания индексов.Repair with keycache
Код восстановления использует создание ключей один за другим, через кэш ключей. Это намного медленнее, чемRepair by sorting
.Searching rows for update
Поток осуществляет первую фазу - производит поиск всех совпадающих строк, чтобы затем обновить их. Это действие необходимо выполнить, если командаUPDATE
изменяет индекс, который используется для поиска указанных строк.Sleeping
Поток ожидает, когда клиент направит ему новую команду.System lock
Поток ожидает получения внешней системной блокировки таблицы. Если не используется несколько серверовmysqld
, которые получают доступ к одним и тем же таблицам, системную блокировку можно отключить при помощи параметра--skip-external-locking
.Upgrading lock
ОбработчикINSERT DELAYED
пытается заблокировать таблицу, чтобы вставить строки.Updating
Поток производит поиск строк, которые необходимо обновить, и обновляет их.User Lock
Поток ожидаетGET_LOCK()
.Waiting for tables
Поток получил уведомление, что структура таблицы изменилась, и ему необходимо повторно открыть таблицу, чтобы получить новую структуру. Чтобы повторно открыть таблицу, он должен подождать, пока ее не закроют все остальные потоки. Это уведомление выдается, если другой поток воспользовался командойFLUSH TABLES
или к таблице была применена одна из следующих команд:FLUSH TABLES table_name
,ALTER TABLE
,RENAME TABLE
,REPAIR TABLE
,ANALYZE TABLE
илиOPTIMIZE TABLE
. ОбработчикINSERT DELAYED
завершил работу со всеми вставками и ожидает новые.
Большинство состояний - это очень быстрые операции. Если потоки остаются в любом из этих состояний на протяжении большого количества секунд, то, возможно, возникла какая-то проблема, которую следует устранить.
Существует еще несколько состояний, не упомянутых выше, но большинство из
них полезны только для поиска ошибок в mysqld
.
4.5.6.7 SHOW GRANTS
SHOW GRANTS FOR user выводит список команд назначения привилегий, которые нужны при дублировании привилегий для пользователя.
mysql> SHOW GRANTS FOR root@localhost; +---------------------------------------------------------------------+ | Grants for root@localhost | +---------------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'root'ĺocalhost' WITH GRANT OPTION | +---------------------------------------------------------------------+
Для получения информации по привилегии в текущей сессии можно использовать
функцию CURRENT_USER()
(новшество в версии 4.0.6) для того, чтобы
выяснить, по какому пользователю в действительности аутентифицировалась сессия.
See section 6.3.6.2 Разные функции.
4.5.6.8 SHOW CREATE TABLE
Показывает оператор CREATE TABLE
, который будет создавать данную таблицу:
mysql> SHOW CREATE TABLE t\G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE t ( id int(11) default NULL auto_increment, s char(60) default NULL, PRIMARY KEY (id) ) TYPE=MyISAM
Команда SHOW CREATE TABLE
будет выдавать таблицу и названия столбцов
в соответствии с параметром SQL_QUOTE_SHOW_CREATE
. See section 5.5.6 Синтаксис команды SET
.
4.5.6.9 SHOW WARNINGS | ERRORS
SHOW WARNINGS [LIMIT #] SHOW ERRORS [LIMIT #]
Эта команда реализована в версии MySQL 4.1.0.
Команда показывает информацию по ошибкам, предупреждениям и сообщениям, касающихся последней команды. Эти сообщения сбрасываются для каждой новой команды, использующей таблицы.
Сервер MySQL возвращает общее количество сообщений и ошибок, которые вы
получили для последней команды. Это количество можно получить вызовом
mysql_warning_count()
.
Максимум max_error_count
сообщений сохраняется (переменная глобальная и
специфичная для потока).
Вы можете получить количество ошибок из @error_count
и количество
предупреждений из @warning_count
.
SHOW WARNINGS
сообщает все ошибки, предупреждения и заметки, которые вы получили
для последней команды, в то время как SHOW ERRORS
даешь лишь только информацию по
ошибкам.
mysql> DROP TABLE IF EXISTS нет_такой_таблицы; mysql> SHOW WARNINGS; +-------+------+-----------------------------------+ | Level | Code | Message | +-------+------+-----------------------------------+ | Note | 1051 | Unknown table 'нет_такой_таблицы' | +-------+------+-----------------------------------+
4.5.6.10 SHOW TABLE TYPES
SHOW TABLE TYPES
Эта команда реализована в 4.1.0.
SHOW TABLE TYPES
дает статусную информацию про типы таблиц. Эта
информация полезна, например, для проверки, поддерживается ли определенный тип
таблицы или для того чтобы узнать, какой тип таблиц используется по умолчанию.
mysql> SHOW TABLE TYPES; +--------+---------+----------------------------------------------------------------+ | Type | Support | Comment | +--------+---------+----------------------------------------------------------------+ | MyISAM | DEFAULT | Основной тип для 3.23 с отличной производительностью | | HEAP | YES | Хеш-тип, хранится только в памяти, полезен для временных таблиц| | MERGE | YES | Набор идентичных MyISAM-таблиц | | ISAM | YES | Старый тип; замещен MyISAM | | InnoDB | YES | Поддерживает транзакции, строчную блокировку и внешние ключи | | BDB | NO | Поддерживает транзакции и страничную блокировку | +--------+---------+----------------------------------------------------------------+ 6 rows in set (0.00 sec)
Опция DEFAULT
в столбце Support
указывает, что данный конкретный
тип таблицы поддерживается и является принятым по умолчанию. Если сервер был
запущен с --default-table-type=InnoDB
, тогда для InnoDB столбец
Support
примет значение DEFAULT
.
4.5.6.11 SHOW PRIVILEGES
SHOW PRIVILEGES
Эта команда реализована в MySQL 4.1.0.
SHOW PRIVILEGES
показывает список системных привилегий,
которые поддерживаются сервером MySQL.
mysql> show privileges; +------------+--------------------------+-------------------------------------------------------+ | Privilege | Context | Comment | +------------+--------------------------+-------------------------------------------------------+ | Select | Tables | To retrieve rows from table | | Insert | Tables | To insert data into tables | | Update | Tables | To update existing rows | | Delete | Tables | To delete existing rows | | Index | Tables | To create or drop indexes | | Alter | Tables | To alter the table | | Create | Databases,Tables,Indexes | To create new databases and tables | | Drop | Databases,Tables | To drop databases and tables | | Grant | Databases,Tables | To give to other users those privileges you possess | | References | Databases,Tables | To have references on tables | | Reload | Server Admin | To reload or refresh tables, logs and privileges | | Shutdown | Server Admin | To shutdown the server | | Process | Server Admin | To view the plain text of currently executing queries | | File | File access on server | To read and write files on the server | +------------+--------------------------+-------------------------------------------------------+ 14 rows in set (0.00 sec)
Этот же пример в переводе на русский язык:
mysql> show privileges; +------------+--------------------------+-------------------------------------------------------+ | Привилегия | Контекст | Описание | +------------+--------------------------+-------------------------------------------------------+ | Select | Таблица | Для выборки строк из таблицы | | Insert | Таблица | Для вставки данных в таблицы | | Update | Таблица | Для обновления существующих записей | | Delete | Таблица | Для удаления существующих записей | | Index | Таблица | Для создания или удаления индексов | | Alter | Таблица | Для изменения таблиц | | Create | База,Таблица,Индекс | Для создания новых баз данных и таблиц | | Drop | База,Таблица | Для удаления баз данных и таблиц | | Grant | База,Таблица | Для раздачи другим пользователям имеющихся у вас прав | | References | База,Таблица | Для обладания ссылок на таблицы | | Reload | Администрирование | Для обновления таблиц, журналов и привилегий | | Shutdown | Администрирование | Для остановки сервера | | Process | Администрирование | Для просмотра текста выполняющихся запросов | | File | Доступ к файлам | Для чтения и записи файлов на сервере | +------------+--------------------------+-------------------------------------------------------+ 14 rows in set (0.00 sec)
4.6 Локализация MySQL и использование национальных алфавитов
4.6.1 Набор символов, применяющийся для записи данных и сортировки
По умолчанию в MySQL используется набор символов ISO-8859-1 (Latin1) с сортировкой согласно шведским/финским правилам. Этот набор символов также подходит для использования в США и Западной Европе.
Все стандартные исполняемые файлы MySQL компилируются с настройкой
--with-extra-charsets=complex
. Таким образом в файл помещается код,
позволяющий всем стандартным программам работать с набором символов
latin1
, а также многобайтовыми наборами символов. Другие наборы символов
могут загружаться из соответствующих файлов определений по необходимости.
Набор определяет, какие символы могут использоваться в именах, а также
способ сортировки значений в операторах ORDER BY
и GROUP BY
команды
SELECT
.
При запуске сервера можно изменить набор символов при помощи параметра
--default-character-set
. Выбрать доступные наборы символов можно при
помощи параметров --with-charset=charset
и --with-extra-charsets=
список-кодировок | complex | all
, и файлов наборов символов, перечисленных
в SHAREDIR/charsets/Index
. See section 2.3.3 Типичные опции configure
.
При смене набора символов во время работы MySQL (что может одновременно
изменить и порядок сортировки) необходимо запустить команду myisamchk -r
-q --set-character-set=charset
для всех таблиц. В противном случае индексы
могут быть созданы в неправильном порядке.
При подключении клиента к серверу MySQL сервер отправляет ему используемый по умолчанию набор символов. На время соединения клиент переключается на использование этого набора.
Для экранирования строк в SQL-запросе необходимо пользоваться функцией
mysql_real_escape_string()
. mysql_real_escape_string()
идентична старой
функции mysql_escape_string()
- во всем, кроме одного: в качестве первого
параметра она принимает дескриптор соединения MYSQL.
Если клиент был скомпилирован с набором путей, в которых не было пути установки сервера, а настраивавший MySQL пользователь на включил в исполняемый файл системы все наборы символов, клиенту необходимо сообщить о местонахождении дополнительных наборов символов, которые нужны ему для общения с сервером.
Сделать это можно путем внесения в файл настроек MySQL следующей строки:
[client] character-sets-dir=/usr/local/mysql/share/mysql/charsets
путь в ней указывает на каталог, в котором хранятся динамические наборы символов MySQL.
Заставить клиента использовать определенный набор символов можно следующим образом:
[client] default-character-set=character-set-name
но обычно этого не требуется.
4.6.1.1 Набор символов немецкого алфавита
Для задания порядка сортировки в соответствии с немецким алфавитом нужно
запустить mysqld
с параметром --default-character-set=latin1_de
.
При сортировке и сравнении строк осуществляется следующая подстановка:
Д -> ae Ж -> oe Э -> ue ъ -> ss
Все символы с диакритическими знаками заменяются их аналогами из верхнего регистра и без ударения. Все буквы переводятся в верхний регистр.
При сравнении строк с помощью команды LIKE
, подстановки двух символов
вместо одного не происходит. Все буквы переводятся в верхний регистр.
Диакритические знаки снимаются со всех букв, кроме: э
, Э
, ж
, Ж
, д
и Д
.
4.6.2 Сообщения об ошибках на языках, отличных от английского
mysqld
может выдавать сообщения об ошибках на следующих языках: чешском,
датском, голландском, английском (по умолчанию), эстонском, французском,
немецком, греческом, венгерском, итальянском, японском, корейском,
норвежском, новонорвежском, польском, португальском, румынском, русском,
словацком, испанском и шведском.
При запуске mysqld
выбрать определенный язык можно при помощи настройки
--language=язык
или -L язык
. Например:
shell> mysqld --language=swedish или: shell> mysqld --language=/usr/local/share/swedish
Обратите внимание: названия языков вводятся в нижнем регистре.
Файлы языков по умолчанию располагаются в папке `mysql_base_dir/share/LANGUAGE/'.
Для того чтобы изменить тексты сообщений об ошибках, нужно отредактировать файл `errmsg.txt' и запустить следующую команду для генерации нового файла `errmsg.sys':
shell> comp_err errmsg.txt errmsg.sys
Установив новую версию MySQL, не забудьте внести те же изменения в новый файл `errmsg.txt'.
4.6.3 Добавление набора символов
Снабдить MySQL новым набором символов можно следующим образом.
Определите, является ли новый набор символов простым или сложным. Если для работы с этим набором никаких специальных процедур обработки строк и поддержки многобайтовых символов не требуется, он является простым. Если вышеперечисленные возможности необходимы, этот набор символов относится к сложным.
Например, наборы latin1
и danish
- простые, а big5
и czech
- сложные.
Для всех приведенных ниже примеров предполагается, что используемый набор
символов называется MYSET
.
Для создания простого набора достаточно сделать следующее:
-
Вставьте имя
MYSET
в конец файла `sql/share/charsets/Index' и присвойте этому набору символов уникальный номер. -
Создайте файл `sql/share/charsets/MYSET.conf'. (в качестве основы можно
использовать файл `sql/share/charsets/latin1.conf'). Правила составления
этого файла очень просты:
- Комментарием считается целая строка, начинающаяся с символа `#'.
- Слова разделяются любым количеством непечатаемых символов.
- При определении набора символов каждое слово должно представлять собой число в шестнадцатеричной системе счисления.
-
Массив ctype занимает первых 257 слов. За ним следуют массивы
to_lower
,to_upper[]
иsort_order[]
, каждый из которых занимает 256 слов.
-
Добавьте имя набора символов в списки
CHARSETS_AVAILABLE
иCOMPILED_CHARSETS
файла `configure.in'. - Перенастройте, перекомпилируйте и протестируйте систему.
Для создания сложного набора необходимо выполнить следующие действия:
- Создайте файл strings/ctype-MYSET.c в исходном дистрибутиве MySQL.
- Вставьте имя MYSET в конец файла sql/share/charsets/Index и присвойте этому набору символов уникальный номер.
- Просмотрите один из существующих файлов ctype-*.c (например strings/ctype-big5.c) и узнайте, что нужно определить. Не забывайте, что имена массивов в вашем файле должны быть похожи на следующие: ctype_MYSET, to_lower_MYSET и т.п. Эти имена соответствуют именам массивов из простого набора символов (see section 4.6.4 Массивы определения символов).
-
В начале файла целесообразно поместить комментарий наподобие
следующего:
/* этот комментарий разбирается configure для создания ctype.c, поэтому не меняйте его, если не уверены в правильности своих действий. * .configure. number_MYSET=MYNUMBER .configure. strxfrm_multiply_MYSET=N .configure. mbmaxlen_MYSET=N */
Программа configure использует этот комментарий для линкования набора символов с библиотекой MySQL. Значение строк strxfrm_multiply и mbmaxlen будет разъяснено ниже. Использовать их нужно только в том случае, если вам нужны функции для сортировки строк или работы с многобайтовыми наборами символов соответственно. -
После этого нужно создать некоторые из следующих функций:
my_strncoll_MYSET()
my_strcoll_MYSET()
my_strxfrm_MYSET()
my_like_range_MYSET()
-
Добавьте имя набора символов в списки
CHARSETS_AVAILABLE
иCOMPILED_CHARSETS
файла `configure.in'. - Перенастройте, перекомпилируйте и протестируйте систему.
Более подробные инструкции приведены в файле `sql/share/charsets/README'.
Если вы хотите, чтобы ваш набор символов был включен в комплект поставки MySQL, вышлите патч с ним по адресу internals@lists.mysql.com.
4.6.4 Массивы определения символов
Простые массивы to_lower[]
и to_upper[]
содержат символы верхнего и
нижнего регистров, соответствующие каждому из символов набора. Например:
to_lower['A'] should contain 'a' to_upper['a'] should contain 'A'
sort_order[]
- карта, устанавливающая правила упорядочивания символов для
сравнения и сортировки. Во многих наборах символов эта таблица совпадает с
to_upper[]
(благодаря чему при сортировке регистр символов не
учитывается). MySQL сортирует символы в соответствии со значением
sort_order[символ]
. Более сложные правила упорядочивания строк
разъясняются ниже. See section 4.6.5 Поддержка упорядочивания строк.
ctype[]
представляет собой массив битов, по одному элементу на каждый из
символов. (Массивы to_lower[]
, to_upper[]
, и sort_order[]
индексируются по
значению символа, а ctype[]
- по значению символа + 1. Это позволяет
обрабатывать символы EOF
).
В файле `m_ctype.h' приведены следующие определения битовых масок:
#define _U 01 /* верхний регистр */ #define _L 02 /* нижний регистр */ #define _N 04 /* число (цифра) */ #define _S 010 /* символ пробела */ #define _P 020 /* знак пунктуации */ #define _C 040 /* управляющий символ */ #define _B 0100 /* пустой символ */ #define _X 0200 /* шестнадцатеричная цифра */
Значение ctype[]
для каждого из символов должно представлять собой
объединение значений битовых масок, описывающих символ. Например, 'A'
представят собой символ верхнего регистра (_U
) а также шестнадцатеричную
цифру (_X
), поэтому элемент ['A'+1]
должен содержать значение:
_U + _X = 01 + 0200 = 0201
4.6.5 Поддержка упорядочивания строк
Если правила сортировки вашего естественного языка слишком сложны и не
могут быть заданы с помощью простой таблицы sort_order
[], необходимо
использовать функции упорядочивания строк.
В настоящее время лучшим справочным пособием по этому вопросу являются уже
реализованные наборы символов. Примером такой реализации могут служить
наборы big5
, czech
, gbk
, sjis
и tis160
.
В начале файла в особом комментарии необходимо указать значение
strxfrm_multiply_MYSET=N
. Значение N
представляет собой максимальный
прирост объема строк во время my_strxfrm_MYSET
(т.е. положительное целое
число).
4.6.6 Поддержка многобайтовых символов
При желании обеспечить поддержку нового набора, содержащего многобайтовые символы, нужно пользоваться специальными функциями для работы с многобайтовыми символами.
В настоящее время лучшим справочным пособием по этому вопросу являются уже
реализованные наборы символов. Примером такой реализации могут служить
наборы euc_kr
, gb2312
, gbk
, sjis
и ujis
. Они реализованы в файлах
`ctype-'charset'.c', расположенных в папке `strings'.
В начале файла в особом комментарии необходимо указать значение
strxfrm_multiply_MYSET=N
. Значение N
должно содержать объем самого
``большого'' символа набора в байтах.
4.6.7 Проблемы с наборами символов
При попытке воспользоваться набором символов, не включенным в исполняемый файл, можно столкнуться со следующими неприятностями:
-
В программе задан неверный путь к каталогу, в котором хранятся наборы
символов (по умолчанию это `/usr/local/mysql/share/mysql/charsets').
Данную проблему можно решить с помощью настройки
--character-sets-dir
. - Набор символов является многобайтовым и не может быть загружен динамически. В таком случае нужно перекомпилировать программу и включить в нее поддержку нужного набора.
- Набор символов может быть загружен динамически, но конфигурационного файла для него нет. В таком случае нужно скопировать файл для этого набора из нового дистрибутива MySQL.
-
В файле `Index' нет имени набора символов.
ERROR 1105: File '/usr/local/share/mysql/charsets/?.conf' not found (Errcode: 2)
В таком случае нужно либо установить новый файл `Index' или вручную внести в него недостающие имена наборов.
Узнать имя набора символов таблиц MyISAM
можно с помощью команды myisamchk
-dvv table_name
.
4.7 Серверные сценарии и утилиты MySQL
4.7.1 Обзор серверных сценариев и утилит
Все программы MySQL имеют множество различных опций. При этом каждая
программа MySQL поддерживает опцию --help
, которую можно использовать
для получения полного описания различных опций программы. Например,
попробуйте выполнить mysql --help
.
Заданные по умолчанию опции для всех стандартных программ можно переопределять при помощи файла опций. See section 4.1.2 Файлы параметров `my.cnf'.
В следующем списке приводятся краткие описания серверных программ MySQL:
myisamchk
-
Утилита, используемая для описания, проверки, оптимизации и восстановления
таблиц MySQL. Поскольку утилита
myisamchk
имеет много функций, она описывается в отдельном разделе. See section 4 Администрирование баз данных. make_binary_distribution
-
Создает бинарную поставку откомпилированного кода MySQL. Эту версию при
помощи
FTP
можно передать на сайтsupport.mysql.com
в директорию `/pub/mysql/Incoming', чтобы ею могли воспользоваться и другие пользователи MySQL. mysqlbug
- Сценарий, составляющий отчет о возникшей в MySQL неполадке. Этот сценарий должен всегда использоваться для составления отчета для почтового списка рассылки MySQL.
mysqld
- Сам сервер MySQL, демон. Он должен работать постоянно.
mysql_install_db
- Создает таблицы привилегий MySQL с заданными по умолчанию привилегиями. Это обычно делается только один раз, при первой инсталляции MySQL в системе.
4.7.2 safe_mysqld
, оболочка mysqld
В MySQL 4.0 safe_mysqld
был переименован в mysqld_safe
.
safe_mysqld
- это сценарий, с помощью которого рекомендуется запускать
демон mysqld на Unix. safe_mysqld
служит для реализации неких
дополнительных функций безопасности для mysqld
, таких как возможность
перезапуска сервера при обнаружении ошибки и записи в журнал информации о
процессе работы mysqld
.
Если не указаны опции --mysqld=#
или --mysqld-version=#
, safe_mysqld
будет использовать исполняемый файл mysqld
-max, если последний существует.
Если mysqld-max
не существует, safe_mysqld
запустит mysqld
. Это позволяет
легко выяснить, что даст использование mysqld-max
вместо mysqld
: просто
скопируйте mysqld-max
поверх mysqld
, и он будет работать.
Как правило, редактировать сценарий safe_mysqld
не следует, однако можно
указать опции для safe_mysqld
, поместив их в раздел [safe_mysqld]
файла
`my.cnf'. safe_mysqld
будет считывать все опции из разделов файлов опций
[mysqld]
, [server]
и [safe_mysqld]
. See section 4.1.2 Файлы параметров `my.cnf'.
Обратите внимание: все опции, которые вводятся в командной строке для
safe_mysqld
, передаются mysqld
. Если требуется применить в safe_mysqld
какие-либо опции, которые mysqld
не поддерживает, эти опции нужно
определить в файле опций.
Большинство опций safe_mysqld
- те же, что и у mysqld
. See section 4.1.1 Параметры командной строки mysqld
.
Safe_mysqld
поддерживает следующие опции:
--basedir=path
--core-file-size=#
-
Размер
core
-файла который может быть созданmysqld
. Значение передаетсяulimit -c
--datadir=path
--defaults-extra-file=path
--defaults-file=path
--err-log=path (устарело в 4.0; Используйте --log-error вместо)
--log-error=path
- Писать журнал ошибок в указанный файл. See section 4.9.1 Журнал ошибок.
--ledir=path
-
Путь к
mysqld
--log=path
--mysqld=mysqld-version
-
Имя версии
mysqld
, которую вы хотите запустить в директории `ledir' --mysqld-version=version
-
То же, что и
--mysqld=
, но в этой опции задается только суффикс дляmysqld
. Например, если используется--mysqld-version=max
,safe_mysqld
запустит версиюledir/mysqld-max
. Если задать--mysqld-version
без аргумента, будет использоватьсяledir/mysqld
. --no-defaults
--open-files-limit=#
-
Максимальное количество файлов, которые могут быть открыты
mysqld
. Значение передаетсяulimit -n
. Обратите внимание: чтобы эта опция работала корректно, необходимо запуститьsafe_mysqld
от пользователя root! --pid-file=path
--port=#
--socket=path
--timezone=#
-
Устанавливает переменную часового пояса (
TZ
) в значение, передаваемое в этом параметре. --user=#
Сценарий safe_mysqld
написан таким образом, чтобы можно было запустить
сервер, инсталлированный как из исходного кода, так и из бинарной поставки
MySQL, даже если компоненты сервера, в зависимости от используемой
инсталляции, будут размещены несколько по-другому. Для safe_mysqld
требуется выполнение одного из следующих условий:
-
Сервер и базы данных можно обнаружить относительно каталога, в котором
вызывается
safe_mysqld
.safe_mysqld
ищет в своей рабочей директории `bin' и `data' (для бинарных дистрибутивов) или `libexec' и `var' (для дистрибутивов с исходным кодом). Это условие должно выполняться, еслиsafe_mysqld
запускается из директории, в которую инсталлирован MySQL (например `/usr/local/mysql' для бинарного дистрибутива). -
Если сервер и базы данных не могут быть найдены относительно рабочей
директории,
safe_mysqld
пытается найти их по абсолютным путям. Типичные местоположения - `/usr/local/libexec' и `/usr/local/var'. Действительные местоположения определяются при создании дистрибутива, из которого запускаетсяsafe_mysqld
. Они должны быть корректными, если MySQL был инсталлирован в стандартное местоположение.
Поскольку safe_mysqld
будет пытаться найти сервер и базы данных
относительно собственной рабочей директории, можно инсталлировать двоичный
дистрибутив MySQL куда угодно, при условии, что safe_mysqld
будет
запускаться из директории, в которой установлен MySQL:
shell> cd mysql_installation_directory shell> bin/safe_mysqld &
Если safe_mysqld
не может запустить сервер, даже в том случае, когда он
вызывается из инсталляционной директории MySQL, сценарий safe_mysqld
можно
модифицировать так, чтобы он использовал верный путь к mysqld
и опции
путей, которые являются правильными для вашей системы. Обратите внимание:
если в будущем вы будете делать апгрейд MySQL, новая версия safe_mysqld
будет записана поверх старой, поэтому нужно сделать копию
отредактированной версии, которую вы сможете затем установить повторно.
4.7.3 Mysqld_multi
, программа для управления множеством серверов MySQL
Программа mysqld_multi
предназначена для управления несколькими процессами
mysqld
, работающих на различных сокетах Unix и портах TCP/IP.
Программа будет искать группу(группы) [mysqld#]
в `my.cnf' (или
заданных при помощи --config-file=...
файлах), где #
- любое
положительное число, начиная с 1. Мы говорим про этот номер далее как про номер
группы опций, или GNR. Номера групп различают группы опций одну от другой и
используются как аргумент при запуске mysqld_multi
чтобы указать, какие сервера
вы хотите запустить, остановить или получить статус об. Эти группы должны быть
такими же, как и обычная группа [mysqld
] (например содержать опции для
mysqld
; см. в руководстве более подробную информацию), но с такими
портом, сокетом и т.д., которые требуются для каждого отдельного процесса
mysqld
.
mysqld_multi
запускается в таком синтаксисе:
Использование: mysqld_multi [OPTIONS] {start|stop|report} [GNR,GNR,GNR...] или mysqld_multi [OPTIONS] {start|stop|report} [GNR-GNR,GNR,GNR-GNR,...]
GNR здесь означает номер группы. Можно запускать, останавливать или создавать отчеты о любом GNR, или о нескольких из них одновременно. Получить пример о том, как бы вы могли настроить файл опций, можно так:
shell> mysqld_multi --example
В качестве разделителей в списке GNR применяются запятые, комбинации создаются при помощи тире. Последнее означает, что будут задействованы все номера GNR из диапазона GNR1-GNR2. Если не задан аргумент GNR, то все группы будут либо запущены, либо остановлены, либо будет выведен отчет об этих группах. Обратите внимание, что в списке GNR не должно быть никаких пропусков (пробелов, символов табуляции или пустых строк). Любые данные после пропуска будут игнорироваться.
mysqld_multi поддерживает следующие опции:
--config-file=...
-
Альтернативный файл конфигурации (
config file
). Примечание: данный файл не влияет на собственные опции этой программы (группа[mysqld_multi]
), а только на группы[mysqld#]
. Без этой опции поиск всех данных будет осуществляться только в обычном файле `my.cnf'. --example
- Представляет пример файла конфигурации.
--help
- Выводит справочную информацию и завершает работу.
--log=...
- Файл журнала. Имя файла журнала и полный путь к нему. Примечание: если файл существует, записи будут добавляться в конец файла.
--mysqladmin=...
-
Исполняемый файл
mysqladmin
, используемый для завершения работы сервера. --mysqld=...
-
Исполняемый файл
mysqld
, который будет использоваться. Обратите внимание: в этой опции можно также указыватьsafe_mysqld
. Опции передаютсяmysqld
. Необходимо только удостовериться, что в переменной окружения PATH имеетсяmysqld
или что установленsafe_mysqld
. --no-log
-
Вывод в
stdout
вместо журнала. По умолчанию журналы включены. --password=...
-
Пароль пользователя для доступа к
mysqladmin
. --tcp-ip
- Подсоединение к серверу(ам) MySQL по TCP/IP вместо Unix-сокетов. Данная опция влияет на завершение работы сервера и создание отчетов. Если файл сокета отсутствует, сервер будет работать, но к нему можно будет обращаться только через порт TCP/IP. По умолчанию соединение осуществляется через сокет Unix.
--user=...
-
Имя пользователя MySQL для
mysqladmin
. --version
- Вывод номера версии и завершение работы.
Некоторые примечания относительно mysqld_multi:
-
Удостоверьтесь, что пользователь MySQL, останавливающий
mysqld
(например, при помощиmysqladmin
), имеет один пароль и имя пользователя для всех директорий данных, к которым производится доступ (имеется в виду - к базе данныхmysql
). Убедитесь также, что пользователь имеет привилегиюShutdown_priv
! Если имеется несколько директорий с данными и несколько различных баз данныхmysql
с различными паролями для пользователяroot
в MySQL, можно создать некоего общего пользователяmulti_admin
для всех, с одинаковым паролем (см. ниже). Сделать это можно так:shell> mysql -u root -S /tmp/mysql.sock -proot_password -e "GRANT SHUTDOWN ON *.* TO multi_admin@localhost IDENTIFIED BY
See section 4.2.6 Как работает система привилегий. Эти действия нужно выполнять для каждогоmysqld
для каждой имеющейся директории данных (для этого нужно выбрать другой сокет-S=...
). -
`pid-файл' играет очень важную роль, если для запуска
mysqld
используется сценарийsafe_mysqld
(например,--mysqld=safe_mysqld
). Преимущество использованияsafe_mysqld
вместоmysqld
заключается в том, чтоsafe_mysqld
``бережет'' каждый процессmysqld
и перезапустит его, еслиmysqld
-процесс умрет по сигналу 9 или подобному (например, в случае ошибки сегментации - хотя, конечно, уж этой ошибки MySQL в принципе совершать не должен;). Пожалуйста, обратите внимание: может оказаться, что сценарийsafe_mysqld
требуется запускать из определенного каталога. Это означает, что прежде чем запуститьmysqld_multi
, прийдется перейти в нужный каталог. Если при запуске возникнут проблемы, пожалуйста, просмотрите сценарийsafe_mysqld
. Обратите внимание на следующие строки:-------------------------------------------------------------------------- MY_PWD=`pwd` Check if we are starting this relative (for the binary release) if test -d /data/mysql -a -f ./share/mysql/english/errmsg.sys -a -x ./bin/mysqld -------------------------------------------------------------------------- See section 4.7.2
Этот тест может пройти успешно, однако возможны и проблемы.safe_mysqld
, оболочкаmysqld
. -
Не запускайте несколько демонов
mysqld
с одной и тожй же директорией данных. Используйте различные директории с данными, если Вы четко не уверены в своих действиях! -
Файл сокета и порт TCP/IP должны быть различными для каждого демона
mysqld
. -
Первая и пятая группы
mysqld
были преднамеренно не включены в пример. В файле конфигурации могут быть ``промежутки'' - это увеличивает гибкость. Порядок, в котором запускаются или завершают работу демоныmysqld
, зависит от порядка, в котором они указаны в файле конфигурации. -
Когда нужно обратиться к некоторой группе (GNR) в этой программе,
просто используйте номер в конце имени группы. Например, GNR для группы
[mysqld17]
- 17. -
Для
mysqld
можно использовать опцию--user
, но для этого сценарийmysqld_multi
должен быть запущен отroot
. Наличие опции в файле конфигурации не имеет значения; вы получите предупреждение только в случаях, если не являетесь суперпользователем и демонmysqlds
запущен под вашим аккаунтом Unix. Важно: удостоверьтесь, что дляpid-файла
и директории с данными имеется доступ для чтения+записи(+выполнения - для директории с данными) для того пользователя Unix, который запускает определенный процессmysqld
. Не используйте для этого аккаунтroot
в Unix, если Вы не уверены в своих действиях! -
Очень важно: удостоверьтесь, что вы понимаете значения опций, которые
передаются демонам
mysqld
, и что осознаете то, почему могут быть нужны отдельные процессыmysqld
. Запуск нескольких демоновmysqld
с одной директорией данных не увеличит производительность в многопоточной системе!
See section 4.1.4 Запуск нескольких серверов MySQL на одном компьютере.
Пример файла конфигурации для mysqld_multi
.
# Этот файл может находиться в вашей домашней директории (~/.my.cnf) или /etc/my.cnf # Version 2.1 by Jani Tolonen [mysqld_multi] mysqld = /usr/local/bin/safe_mysqld 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
See section 4.1.2 Файлы параметров `my.cnf'.
4.7.4 myisampack
, MySQL-генератор сжатых таблиц (только для чтения)
Утилита myisampack
используется для сжатия таблиц MyISAM
, а утилита
pack_isam
- для сжатия таблиц ISAM
. Поскольку таблицы ISAM
являются
устаревшими, здесь будет рассматриваться только myisampack
, но все,
сказанное относительно myisampack
, справедливо также и для pack_isam
.
myisampack
сжимает каждый столбец в таблице по отдельности. Информация,
необходимая для декомпрессии столбцов, считывается в память при открытии
таблицы. В результате обеспечивается более высокая производительность при
доступе к отдельным записям, поскольку нужно распаковывать только одну
запись, а не значительно больший по размеру дисковый блок, как при
использовании программы Stacker в MS DOS. В среднем myisampack
сжимает
файл данных на 40%-70%.
(MySQL использует отображение в памяти (mmap()
) для сжатых таблиц
а если mmap()
не работает, возвращается назад к нормальному режиму
чтения/записи.
Обратите внимание на следующее:
- После сжатия таблица доступна в режиме только для чтения. Это удобно, скажем, для записи на CD. Реализация возможности записи в сжатые таблицы находится в нашем списке задач к выполнению, но имеет низкий приоритет.
-
myisampack
может также сжимать столбцы c типамиBLOB
илиTEXT
. В предыдущей версииpack_isam
(для таблицISAM
) данной функции не было.
Утилиту myisampack
можно запустить следующим образом:
shell> myisampack [options] filename ...
Каждое имя файла (filename
) должно быть именем индексного файла (`.MYI').
Если вы не находитесь в директории базы данных, необходимо указать полный
путь к файлу. Допускается опускать расширение `.MYI'.
myisampack поддерживает следующие опции:
-b, --backup
- Создает резервную копию таблицы, присваивая ей имя `tbl_name.OLD'.
-#, --debug=debug_options
-
Выводить журнал отладки. Строка
debug_options
часто принимает значениеd:t:o,filename
-f, --force
-
Сжатие таблицы происходит, даже если она увеличивается или если существует
временный файл. Во время сжатия таблицы
myisampack
создает временный файл `tbl_name.TMD'. Если вы вручную прекратите выполнениеmyisampack
, может оказаться так, что файл `tbl_name.TMD' не будет удален. Обычно еслиmyisampack
обнаруживает существующий `tbl_name.TMD', она прекращает работу и выдает ошибку. При указании опции--force
myisampack
сжимает таблицу в любом случае. -?, --help
- Выдает справочную информацию и завершает работу.
-j big_tbl_name, --join=big_tbl_name
-
Соединяет все таблицы, указанные в командной строке, в одну таблицу
big_tbl_name
. Все таблицы, подлежащие объединению, должны быть идентичными (одинаковые имена и типы столбцов, одинаковые индексы и т.д.). -p #, --packlength=#
-
Определяет разрядность поля, хранящего длину строки, в байтах. Может
принимать значения 1, 2 или 3. (
myisampack
хранит все строки с указателями длины размером в 1, 2, или 3 байта. В большинстве случаевmyisampack
способна определить правильное значение длины перед началом сжатия файла, но во время сжатия она может обнаружить, что может быть использована более короткая длина. В этом случаеmyisampack
выведет сообщение о том, что в следующий раз при сжатии данного файла можно использовать более короткую длину записи.) -s, --silent
- Молчаливый режим. Сообщения выводятся только при возникновении ошибок.
-t, --test
- Сжатие таблицы не выполняется, происходит только проверка процедуры сжатия.
-T dir_name, --tmp_dir=dir_name
- Указанная директория используется как местоположение для создания временной таблицы.
-v, --verbose
- Расширенный режим вывода сообщений. Выводится информация о состоянии процесса и результаты сжатия.
-V, --version
- Отображает информацию о версии и завершает работу.
-w, --wait
-
Если таблица уже используется, подождать повторить попытку. Если сервер
mysqld
был вызван с опцией--skip-external-locking
, то не самая лучшая идея - вызыватьmyisampack
, если таблица может модифицироваться во время процесса сжатия.
Последовательность приведенных ниже команд иллюстрирует типичный сеанс сжатия таблицы:
shell> ls -l 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 -dvv station MyISAM 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 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 87.14% shell> ls -l 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 -dvv station MyISAM 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 Datafilepointer (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(1) 2 9 3 6 4 no zeros, zerofill(1) 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(1) 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(1) 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(1) 2 9 28 369 4 no zeros, zerofill(1) 2 9 29 373 4 table-lookup 11 0 30 377 1 3 9 31 378 2 no zeros, zerofill(1) 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(1) 13 9 36 400 4 no zeros, zerofill(1) 2 9 37 404 1 2 9 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(1) 2 9
Ниже приведено описание вывода myisampack:
normal
- Количество столбцов, для которых не используется никакого дополнительного сжатия.
empty-space
- Количество столбцов, содержащих пустые значения; эти занимают по 1 биту.
empty-zero
- Количество целочисленных столбцов, в которых содержатся только двоичные нули (ascii 0); каждый из них будет занимать 1 бит
empty-fill
-
Количество целочисленных столбцов, значения которых не полностью занимают
отведенную для них разрядность в байтах; тип этих столбцов изменяется на
тип с меньшей разрядностью(например, столбец
INTEGER
может быть изменен наMEDIUMINT
). pre-space
- Количество десятичных столбцов, которые хранятся с начальными пробелами. В этом случае каждое значение будет содержать число ведущих пробелов.
end-space
- Количество столбцов, имеющих много оконечных пробелов. В этом случае каждое значение будет содержать число таких пробелов.
table-lookup
-
Столбец имеет только небольшое количество различающихся значений, которые
перед сжатием Хаффмана (Huffman) конвертируются в
ENUM
. zero
- Количество столбцов, все значения которых являются нулями.
Original trees
- Начальное количество деревьев Хаффмана.
After join
- Количество различных деревьев Хаффмана, оставленных после соединения деревьев для сохранения немного пространства в заголовках.
После сжатия таблицы myisamchk -dvv
выводит дополнительную информацию по
каждому полю:
Type
-
Тип поля может содержать следующие дескрипторы:
constant
- Все строки содержат одинаковое значение.
no endspace
- Не сохраняются замыкающие пробелы.
no endspace, not_always
- Не сохраняются замыкающие пробелы и не производится сжатие за счет замыкающих пробелов для всех значений.
no endspace, no empty
- Не сохраняются замыкающие пробелы. Не сохраняются пустые значения.
table-lookup
-
Столбец был преобразован к
ENUM
. zerofill(n)
- В значении n главных байтов всегда являются 0 и не сохранены.
no zeros
- Не сохраняются нули.
always zero
- Значения 0 хранятся в 1 бите.
Huff tree
- Дерево Хаффмана, связанное с полем.
Bits
- Количество битов, используемых в дереве Хаффмана.
После запуска pack_isam
/myisampack
нужно запустить isamchk
/myisamchk
для
повторного создания индекса. В это время можно также отсортировать
индексные блоки и создать статистику, необходимую для более эффективной
работы оптимизатора MySQL:
myisamchk -rq --analyze --sort-index table_name.MYI isamchk -rq --analyze --sort-index table_name.ISM
После установки сжатой таблицы в директорию базы данных MySQL нужно
проделать операцию mysqladmin flush-tables
, чтобы сервер mysqld
начал
использовать новую таблицу.
Для распаковки сжатой таблицы можно использовать опцию --unpack
isamchk
или myisamchk
.
4.7.5 mysqld-max
, расширенный сервер mysqld
mysqld-max
- это сервер MySQL (mysqld
), скомпилированный со следующими
конфигурационными опциями:
Опция | Описание |
--with-server-suffix=-max | Добавляет суффикс к версии mysqld .
|
--with-innodb | Поддержка таблиц InnoDB. |
--with-bdb | Поддержка таблиц Беркли DB (BDB) |
CFLAGS=-DUSE_SYMDIR | Символические ссылки для Windows. |
Бинарную версию MySQL-max можно найти по адресу http://www.mysql.com/downloads/mysql-max-3.23.php.
Бинарные дистрибутивы Windows MySQL включают стандартный двоичный файл
mysqld.exe
а также двоичный файл mysqld-max.exe
.
http://www.mysql.com/downloads/mysql-3.23.php. See section 2.1.2 Установка MySQL на Windows.
Обратите внимание: поскольку таблицы InnoDB и Berkeley DB доступны не для всех платформ, некоторые из двоичных дистрибутивов могут не поддерживать оба этих типа таблиц. Проверить, какие типы таблиц поддерживаются, можно при помощи следующего запроса:
mysql> SHOW VARIABLES LIKE "have_%"; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | have_bdb | YES | | have_innodb | NO | | have_isam | YES | | have_raid | NO | | have_openssl | NO | +---------------+-------+
Значения имеют следующий смысл:
Значение | Описание |
YES | Опция активизирована. |
NO | MySQL не поддерживает эту опцию. |
DISABLED | Опция xxxx заблокирована, потому что mysqld был запущен с параметром --skip-xxxx или потому, что mysqld был запущен не со всеми опциями, необходимыми для того, чтобы использование данной опции было возможным. В этом случае файл `hostname.err' будет содержать причину, по которой опция заблокирована.
|
Примечание: чтобы получить возможность создавать таблицы InnoDB, вы должны
отредактировать опции, включив по меньшей мере опцию
innodb_data_file_path
. See section 7.5.2 Параметры запуска InnoDB.
Чтобы улучшить производительность таблиц BDB, для них нужно также добавить
некоторые конфигурационные опции. See section 7.6.3 Параметры запуска BDB
.
safe_mysqld
будет автоматически пытаться запустить двоичный mysqld
с
суффиксом -max
. Таким образом можно просто осуществлять тестирование
свежесобранного бинарного mysqld
в существующей инсталляции. Для этого
нужно выполнить configure
с требуемыми опциями, собрать, и затем
установить новый mysqld
как mysqld-max
в тот же самый каталог, где
находится ``старый'' бинарный mysqld
. See section 4.7.2 safe_mysqld
, оболочка mysqld
.
mysqld-max
RPM использует вышеупомянутую возможность safe_mysqld
. Он
только устанавливает исполняемый mysqld-max
, и safe_mysqld
будет
автоматически использовать его после перезапуска safe_mysqld
.
В следующей таблице показаны типы таблиц, поддерживаемые двоичным
MySQL-Max
:
System | BDB | InnoDB
|
AIX 4.3 | Нет | Да |
HP-UX 11.0 | Нет | Да |
Linux-Alpha | Нет | Да |
Linux-Intel | Да | Да |
Linux-IA64 | Нет | Да |
Solaris-Intel | Нет | Да |
Solaris-SPARC | Да | Да |
Caldera (SCO) OSR5 | Да | Да |
UnixWare | Да | Да |
Windows/NT | Да | Да |
4.8 Клиентские сценарии и утилиты MySQL
4.8.1 Обзор клиентских сценариев и утилит
Все клиенты MySQL, которые взаимодействуют с сервером с помощью библиотеки
mysqlclient
, используют следующие переменные окружения:
Имя | Описание |
MYSQL_UNIX_PORT | Сокет, используемый по умолчанию для локальных подсоединений |
MYSQL_TCP_PORT | Устанавливаемый по умолчанию порт TCP/IP |
MYSQL_PWD | Устанавливаемый по умолчанию пароль |
MYSQL_DEBUG | Опции пошаговой отладки программ |
TMPDIR | Каталог для создания временных таблиц/файлов |
Использование MYSQL_PWD
небезопасно. See section 4.2.8 Соединение с сервером MySQL.
Клиент mysql
использует файл, указанный в переменной окружения
MYSQL_HISTFILE
, для хранения истории командной строки. Значение по
умолчанию для этого файла истории - $HOME/.mysql_history
, где $HOME
-
значение переменной окружения HOME
. See section E Переменные окружения.
Все программы MySQL принимают множество различных опций. При этом каждая
программа MySQL поддерживает опцию --help
, которую можно использовать для
получения полного описания различных опций программы. Например, попробуйте
запустить mysql --help
.
Для всех стандартных клиентских программ можно переопределить значения опций по умолчанию, используя файл опций. See section 4.1.2 Файлы параметров `my.cnf'.
В приведенном ниже списке дано краткое описание клиентских программ MySQL:
msql2mysql
- Сценарий оболочки операционной системы, преобразующий программы базы данных mSQL к виду, приемлемому для MySQL. Он не обрабатывает всех случаев, но с него хорошо начинать такое преобразование.
mysqlaccess
- Сценарий, который проверяет привилегии доступа для комбинации значений хоста, пользователя и базы данных.
mysqladmin
-
Утилита для выполнения административных функций, таких как создание или
удаление баз данных, перезагрузка таблиц привилегий, запись на диск
содержимого таблиц, находящегося в буфере, повторное открытие файлов
журналов. Утилита
mysqladmin
может также использоваться для получения информации с сервера о номере версии, процессах и состоянии сервера. См. раздел See section 4.8.3mysqladmin
, Администрирование MySQL-сервера.. mysqldump
-
Выводит содержимое базы данных MySQL в виде файла с SQL-операторами или в
виде текстовых файлов с символом табуляции в качестве разделителя.
Усовершенствованная свободно распространяемая утилита, автором которой
является Игорь Романенко. See section 4.8.5
mysqldump
, Получение дампов данных и структуры таблицы. mysqlimport
-
Импортирует текстовые файлы в соответствующие таблицы, используя команду
LOAD DATA INFILE
. See section 4.8.7mysqlimport
, импорт данных из текстовых файлов. mysqlshow
- Отображает информацию о существующих базах данных, таблицах, полях и индексах.
replace
-
Служебная программа, использующаяся в сценарии
msql2mysql
, но имеющая также более широкое применение. Утилитаreplace
изменяет строки, находящиеся в файлах или в стандартных входных данных. Использует принцип конечного автомата, чтобы в первую очередь найти соответствие длинных строк. Может применяться для замены строк. Например, эта команда меняет местамиa
иb
в данных файлах:shell> replace a b b a -- file1 file2 ...
4.8.2 mysql
, Утилита командной строки
Утилита командной строки mysql
является простой SQL-оболочкой (с
возможностями библиотеки readline
проекта GNU). Она поддерживает
интерактивный и неинтерактивный режимы. В интерактивном режиме результаты
запроса представляются в ASCII-формате. При использовании в
неинтерактивном режиме (например, в качестве фильтра) результат
представляется в текстовом формате с символом табуляции в качестве
разделителя (выходной формат можно изменить при помощи параметров
командной строки). Сценарии можно запускать, как показано ниже:
shell> mysql database < script.sql > output.tab
Если возникают проблемы из-за недостатка памяти на данном клиенте,
применяйте параметр --quick
! Это заставит mysql
использовать функцию
mysql_use_result()
вместо функции mysql_store_result()
для получения
результирующей выборки данных.
Использовать mysql
очень легко. Запустите mysql database
или mysql
--user=user_name --password=your_password databas
e. Наберите SQL-команду
прямо в командной строке, завершив ее одним из символов: `;', `\g' или
`\G', и нажмите клавишу ``Ввод''.
Утилита командной строки mysql
поддерживает следующие параметры:
-?, --help
- Вывод справочной информации об использовании программы и выход из нее.
-A, --no-auto-rehash
-
Отключает автоматическое рехеширование.
rehash
следует использовать для получения хеша таблиц и полей. Это обеспечивает более быстрый стартmysql
. --prompt=...
- Устанавливает приглашение на ввод команд в заданном формате.
-b, --no-beep
- Выключает звуковой сигнал об ошибке.
-B, --batch
- Выводит результаты в пакетном режиме с символом табуляции в качестве разделителя, каждая строка с новой строки. Файл истории не используется.
--character-sets-dir=...
- Директория, где находятся наборы символов.
-C, --compress
- Использовать сжатие данных в протоколе сервер/клиент.
-#, --debug[=...]
- Журнал отладки. Значение по умолчанию - 'd:t:o,/tmp/mysql.trace'.
-D, --database=...
- Имя используемой базы данных. Большей частью применяется в конфигурационном файле `my.cnf'.
--default-character-set=...
- Установить набор символов по умолчанию.
-e, --execute=...
-
Выполнить команду и завершить программу (вывод результата как и для
--batch
). -E, --vertical
-
Вывести результаты запроса (строки) по вертикали. Можно произвести вывод
подобным образом и без данного параметра, завершая команды символами
\G
. -f, --force
- Продолжать обработку даже при обнаружении ошибки SQL.
-g, --no-named-commands
-
Выключает именованные команды. Следует использовать только команды вида \*
либо применять именованные команды только в начале строки, заканчивающейся
символом `;'. Начиная с версии 10.9 клиент запускается с этой опцией,
включенной по умолчанию! С опцией
-g
, однако, длинные команды все еще работают с первой строки. -G, --enable-named-commands
- Разрешает именованные команды. Допускаются длинные команды, а также укороченные команды вида \*.
-i, --ignore-space
- Игнорировать пробел после имен функций.
-h, --host=...
- Подсоединиться к базе данных на указанном хосте.
-H, --html
- Вывести выходные данные в виде HTML.
-X, --xml
- Вывести выходные данные в виде XML.
-L, --skip-line-numbers
- Не указывать номера строк для ошибок. Полезно для сравнения результирующих файлов, включающих сообщения об ошибках.
--no-pager
-
Блокирует пейджер (программа постраничного вывода) и выводит результат в
стандартный вывод stdout (в Unix). Смотрите также команду
\h
(интерактивная помощь). --no-tee
-
Блокирует выходной файл. Смотрите также команду
\h
(интерактивная помощь). -n, --unbuffered
- Очищать буфер после каждого запроса.
-N, --skip-column-names
- Не указывать имена столбцов в результатах.
-O, --set-variable var=option
-
Установить значение переменной. Список используемых переменных выводится
через
--help
. Обратите внимание, что--set-variable
не используется в MySQL 4.0. Просто используйте--var=option
. -o, --one-database
- Обновить только базу данных, установленную по умолчанию. Позволяет пропускать обновления другой базы данных в журнале обновления.
--pager[=...]
-
Устанавливает тип данных вывода. По умолчанию это переменная окружения
PAGER
. Ее возможные значения - less, more, cat [> имя файла], и т.д. См. также команду \h (интерактивная помощь). Этот параметр не работает в пакетном (batch) режиме. Пейджер работает только под Unix. -p[password], --password[=...]
-
Пароль, используемый при подсоединении к серверу баз данных. Если в
командной строке пароль не указан, то он запрашивается у пользователя. При
использовании краткой формы
-p
не оставляйте пробел между параметром и значением пароля. -P порт, --port=порт
- Номер порта TCP/IP, используемый для подсоединения.
--protocol=(TCP | SOCKET | PIPE | MEMORY)
- Для указания протокола соединения, который надлежит использовать. Новшество в MySQL 4.1.0.
-q, --quick
- Не кэшировать результат. Выводить его строка за строкой так, как он приходит от сервера. Это может замедлить скорость работы сервера, если вывод результата будет приостановлен. Файл истории не используется.
-r, --raw
-
Показывать значения столбцов без какого-либо преобразования. Используется
с
--batch
. -s, --silent
- Режим молчания. Выводить только сообщения об ошибках.
-S --socket=...
- Файл сокета, используемый для подсоединения.
-t --table
- Выводить результат в табличном формате. Установлено по умолчанию для непакетного режима.
-T, --debug-info
- Выводить некоторые отладочные данные при выходе из программы.
--tee=...
- Присоединить что-либо к выходному файлу. Смотрите также команду \h (интерактивная помощь). Этот параметр не работает в пакетном режиме.
-u, --user=#
- Имя пользователя MySQL, если этот пользователь не является активным в данное время.
-U, --safe-updates[=#], --i-am-a-dummy[=#]
-
Разрешает выполнять только операции
UPDATE
иDELETE
, используя ключи. Более полная информация об этом параметре приведена ниже. Можно сбросить данный параметр, установив в конфигурационном файле `my.cnf' значение аргумента--safe-updates=0
. -v, --verbose
-
Более расширенный режим вывода результатов (
-v -v -v
дает формат вывода таблицы). -V, --version
- Вывод информации о версии и выход из программы.
-w, --wait
- Если соединение с сервером упало, подождать и попытаться восстановить его, вместо того, чтобы прервать работу.
Через параметры командной строки -O
или --set-variable
(в MySQL 4.0 используйте
просто --var=option
) можно также установить следующие переменные:
Имя переменной | По умолчанию | Описание |
connect_timeout | 0 | Число секунд до истечения времени ожидания соединения |
max_allowed_packet | 16777216 | Максимальная величина пакета, посылаемого/принимаемого с сервера |
net_buffer_length | 16384 | Размер буфера для TCP/IP и сокетного соединения |
select_limit | 1000 | Автоматическое ограничение количества команд SELECT при использовании --i-am-a-dummy |
max_join_size | 1000000 | Автоматическое ограничение количества связанных строк при использовании --i-am-a-dummy. |
Если ввести в командной строке help
, программа mysql
выведет список
поддерживаемых ею команд:
mysql> help Команды MySQL help (\h) Выводит данный текст. ? (\h) Синоним для help. clear (\c) Команда очистки. connect (\r) Снова подключиться к серверу. Дополнительные аргументы - db и host. edit (\e) Редактировать текущую команду с помощью $EDITOR. ego (\G) Послать текущую команду MySQL серверу и вывести результат по вертикали. exit (\q) Выйти из программы. То же что и quit. go (\g) Послать текущую команду MySQL серверу. nopager (\n) Блокировать пейджер, выводить через stdout. notee (\t) Не добавлять записи в выходной файл outfile. pager (\P) Установить PAGER [to_pager]. Выводить результаты запроса через PAGER. print (\p) Вывести текущую команду. prompt (\R) Изменить формат приглашения на ввод команд mysql. quit (\q) Выйти из программы. rehash (\#) Восстановить таблицу хэшей. source (\.) Запустить на выполнение файл с SQL-сценарием. Указать имя файла в качестве аргумента. status (\s) Получить информацию о статусе сервера. tee (\T) Установить параметр outfile [to_outfile]. Присоединить что-либо к данному выходному файлу. use (\u) Использовать другую базу данных. Указать имя базы данных в качестве аргумента.
Команда pager
работает только под Unix.
Команда status
дает информацию о текущем соединении и используемом
сервере. Если вы работаете в режиме --safe-updates
, команда status
также
выведет значения переменных для mysql
, которые влияют на ваши запросы.
Для начинающих рекомендуется пользоваться программой mysql
с установленным
параметром (введен в MySQL 3.23.11) --safe-updates
(или --i-am-a-dummy
для
пользователей, выполнивших DELETE FROM table_name
, но забывших указать
аргументы в WHERE
). В этом случае mysql
при установлении соединения
посылает следующую команду MySQL-серверу:
SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=#select_limit#, SQL_MAX_JOIN_SIZE=#max_join_size#"
где #select_limit#
и #max_join_size#
- переменные, которые можно
установить из командной строки mysql. See section 5.5.6 Синтаксис команды SET
.
Результат этого следующий:
-
Не разрешено выполнять команды
UPDATE
илиDELETE
, если не указаны ограничения по ключам в секцииWHERE
. Однако можно заставить выполняться командыUPDATE
/DELETE
, используя операторLIMIT
:UPDATE table_name SET not_key_column=# WHERE not_key_column=# LIMIT 1;
-
Все слишком большие результаты ограничены строками
#select_limit#
. -
SELECT
ы, которые могут потребовать для исполнения количество комбинаций строк более, чем#max_join_size#
, будут прерваны.
Несколько полезных советов по использованию клиента mysql
:
Некоторые данные более удобочитаемы при выводе их по вертикали вместо обычно используемого горизонтального окна вывода. Например, текст, который больше по длине, чем по ширине, и содержит в себе много новых строк, часто намного легче читать в вертикальном представлении.
mysql> SELECT * FROM mails WHERE LENGTH(txt) < 300 lIMIT 300,1\G *************************** 1. row *************************** msg_nro: 3068 date: 2000-03-01 23:29:50 time_zone: +0200 mail_from: Monty reply: monty@no.spam.com mail_to: "Thimble Smith" <tim@no.spam.com> sbj: UTF-8 txt: >>>>> "Thimble" == Thimble Smith writes: Thimble> Hi. I think this is a good idea. Is anyone familiar with UTF-8 Thimble> or Unicode? Otherwise, I'll put this on my TODO list and see what Thimble> happens. Yes, please do that. Regards, Monty file: inbox-jani-1 hash: 190402944 1 row in set (0.09 sec)
Для журналирования можно использовать опции команды tee. Она может
быть запущена с помощью параметра --tee=...
для mysql
или
интерактивно из командной строки вводом команды tee
. Все
представляемые на экране данные будут также добавлены к заданному
файлу. Это может быть очень полезно для целей отладки программы.
Утилиту tee можно блокировать из командной строки командой notee
.
Повторный запуск команды tee
снова включит журналирование. Если при
этом параметр для команды tee
не указан, то будет использоваться
предыдущий файл. Следует учесть, что команда tee
будет записывать
результаты в файл после каждой выполненной команды, как раз перед
появлением командной строки для ввода очередной команды.
При помощи опции --pager[=...]
стал возможным просмотр или поиск
результатов в интерактивном режиме с помощью Unix-программ less
, more
или иных подобных. Если явно не указать аргумент в этом параметре,
клиент mysql
будет искать переменную окружения PAGER
и установит
значение pager
. Программу pager
также можно запустить из интерактивной
командной строки командой pager
и остановить командой nopager
. Команда
может принимать аргумент, который является необязательным; pager
будет
установлена в значение этого аргумента.. Команда pager
может быть
вызвана и без аргумента, но это требует использования опции --pager
или соответствующей установки по умолчанию стандартного вывода stdout
.
Команда pager работает только в Unix, поскольку использует функцию
popen()
, отсутствующую в Windows. Вместо этого в Windows можно
использовать параметр tee
, хотя в ряде ситуаций это менее удобно, чем
применение команды pager
.
Несколько советов касательно команды pager
:
-
Ее можно использовать для записи в файл:
mysql> pager cat > /tmp/log.txt
и результаты будут направлены только в файл. Вызываемые командойpager
программы могут принимать любые допустимые опции:mysql> pager less -n -i -S
- Обратите особое внимание на опцию -S в вышеприведенном примере. Она может быть очень полезна при просмотре результатов. Попробуйте применить ее с горизонтальным выводом (завершайте команды символами '\g', or ';') и с вертикальным (в конце команд - '\G'). Очень громоздкие результаты вывода иногда трудно бывает прочесть с экрана, в этом случае команда less с опцией -S позволит просмотреть результаты в интерактивном режиме слева направо, при этом при появлении строк с длиной больше, чем ширина экрана, их вывод будет продолжен вывод с новой строки. Вывод данных в таких случаях получается более удобочитаемым. При интерактивном вызове команды less с опцией '-S' можно переключать режим ее работы (включено/выключено) из командной строки. Чтобы получить дополнительную информацию относительно less, обращайтесь к описанию команды 'h'.
-
В заключение отметим (если вы этого еще не поняли из предыдущих
примеров :), что существует возможность комбинировать очень сложные
способы обработки результатов. Так, в следующем примере результаты
будут посланы в два различных каталога, смонтированных на двух
различных жестких дисках в /dr1 and /dr2, и, несмотря на это,
результаты можно увидеть на экране посредством команды less:
mysql> pager cat | tee /dr1/tmp/res.txt | \ tee /dr2/tmp/res2.txt | less -n -i -S
Приведенные выше функции можно тоже комбинировать: запустив tee
и
установив pager
в less
, можно просматривать результаты с помощью
Unix-команды less
и при этом одновременно производить запись в файл.
Разница между служебной Unix-утилитой tee
, используемой в программе
pager
, и встроенной в клиент mysql
командой tee
заключается в том, что
встроенная команда tee
работает даже в том случае, если в Unix утилита
tee
недоступна. Встроенная команда tee
также ведет запись всего, что
выводится на экран, тогда как утилита Unix tee
, используемая с pager
,
не делает этого в достаточном объеме. Последнее, но тем не менее
важное обстоятельство состоит в том, что интерактивная команда tee
более удобна для переключения режимов работы включено/выключено, если
при записи в файл иногда возникает необходимость отключить эту
функцию.
Начиная с версии MySQL 4.0.2 можно изменить формат приглашения в командной
строке клиента mysql
.
Возможны следующие опции приглашения:
Опция | Описание |
\v | версия mysqld |
\d | имя используемой базы данных |
\h | имя хоста, к которому производится подсоединение |
\p | номер порта, через который производится подсоединение |
\u | имя пользователя |
\U | полный адрес username@host |
\\ | обратный слэш `\' |
\n | символ новой строки |
\t | табуляция |
\ | пробел |
\_ | пробел с подчеркиванием |
\R | время по военному часовому поясу (0-23) |
\r | время по стандартному часовому поясу (1-12) |
\m | минуты |
\y | два разряда года |
\Y | четыре разряда года |
\D | полный формат даты |
\s | секунды |
\w | день недели в трехбуквенном формате (Mon, Tue, ...) |
\P | Время до полудня/после полудня (am/pm) |
\o | месяц в числовом формате |
\O | месяц в трехбуквенном формате (Jan, Feb, ...) |
\c | Счетчик, подсчитывающий количество вводимых команд |
Символ `\' за которым следует любая другая буква, просто дополняет эту букву.
Установить параметры приглашения можно следующими способами:
- В переменных окружения
-
Можно установить переменную окружения
MYSQL_PS1
для строки приглашения. Например:shell> export MYSQL_PS1="(\u@\h) [\d]> "
- `my.cnf'
- `.my.cnf'
-
Можно установить опцию prompt в любом конфигурационном файле MySQL в
группе
mysql
. Например:[mysql] prompt=(\u@\h) [\d]>\_
- В командной строке
-
Можно установить опцию
--prompt
из командной строки утилитыmysql
. Например:shell> mysql --prompt="(\u@\h) [\d]> " (user@host) [database]>
- В интерактивном режиме
-
Можно также использовать команду
prompt
(или\R
) для изменения настроек приглашения в интерактивном режиме. Например:mysql> prompt (\u@\h) [\d]>\_ PROMPT set to '(\u@\h) [\d]>\_' (user@host) [database]> (user@host) [database]> prompt Возвращение к исходным (по умолчанию) настройкам PROMPT в утилите mysql> mysql>
4.8.3 mysqladmin
, Администрирование MySQL-сервера.
Утилита для выполнения административных операций. Ее синтаксис:
shell> mysqladmin [ПАРАМЕТРЫ] command [command-option] command ...
Список опций, поддерживаемых вашей конкретной версией mysqladmin
, можно
получить, выполнив команду mysqladmin --help
.
Текущая версия mysqladmin
поддерживает следующие команды:
create databasename
- Создать новую базу данных.
drop databasename
- Удалить базу данных и все ее таблицы.
extended-status
-
Выдает расширенный отчет о состоянии сервера (более полный, чем при
команде
status
) flush-hosts
- Сбросить и перезагрузить хосты.
flush-logs
- Сбросить на диск и переоткрыть все журналы.
flush-tables
- Закрыть все открытые таблицы.
flush-privileges
- Перечитать таблицы привилегий.
kill id,id,...
-
Завершить потоки
mysql
с указаннымиthread-id
. password
- Установить новый пароль для сервера баз данных. Изменить старый пароль на новый.
ping
-
Проверить, работает ли сервер
mysqld
. processlist
- Показать список активных потоков на сервере.
reload
- Перезагрузить таблицы привилегий.
refresh
- Выполнить все табличные операции, находящиеся в буфере, закрыть и открыть заново все системные журналы.
shutdown
- Завершить работу сервера баз данных.
slave-start
- Запустить подчиненный дублирующий поток.
slave-stop
- Остановить подчиненный дублирующий поток.
status
- Выдает краткий отчет о состоянии сервера.
variables
- Вывести доступные для использования переменные.
version
- Вывести данные о версии сервера.
Все команды могут сокращаться до их уникальных префиксов. Например:
shell> mysqladmin proc stat +----+-------+-----------+----+-------------+------+-------+------+ | Id | User | Host | db | Command | Time | State | Info | +----+-------+-----------+----+-------------+------+-------+------+ | 6 | monty | localhost | | Processlist | 0 | | | +----+-------+-----------+----+-------------+------+-------+------+ 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
Результат команды mysqladmin
status выводится в виде следующих столбцов:
Столбец | Описание |
Uptime | Количество секунд с момента запуска MySQL-сервера. |
Threads | Количество активных потоков (клиентов). |
Questions | Количество вопросов от клиентов с момента запуска программы mysqld .
|
Slow queries | Количество запросов, потребовавших большее количество секунд, чем установлено в конфигурации ключом long_query_time . See section 4.9.5 Журнал медленных запросов.
|
Opens | Количество таблиц, открытых программой mysqld .
|
Flush table | Количество выполненных команд flush ..., refresh , reload .
|
Open tables | Количество таблиц, открытых в данное время. |
Memory in use | Память, используемая непосредственно программой mysqld (доступно только в случае компиляции MySQL с установленным значением --with-debug=full ).
|
Max memory used | Максимальный объем памяти, использованный непосредственно программой mysqld (доступно только в случае компиляции MySQL с установленным значением --with-debug=full ).
|
При выполнении mysqladmin shutdown
через сокет
(другими словами, через компьютер с запущенным mysqld
) mysqladmin
будет
ожидать, пока на сервере MySQL не будет удален файл pid-file
(в котором
содержится идентификатор процесса `pid' запущенного сервера) чтобы
убедиться, что сервер остановлен должным образом.
4.8.4 Использование mysqlcheck
для сопровождения и аварийного восстановления таблиц.
Начиная с версии MySQL 3.23.38 можно применять новый инструмент для
проверки и восстановления MyISAM
-таблиц. Отличие mysqlcheck
от myisamchk
состоит в том, что утилита mysqlcheck
должна использоваться при работающем
сервере mysqld
, в то время как myisamchk
- при остановленном. Преимущество
же заключается в том, что теперь не нужно останавливать сервер для
проверки или восстановления таблиц.
Утилита mysqlcheck
использует соответствующие команды MySQL-сервера CHECK
,
REPAIR
, ANALYZE
и OPTIMIZE
удобным для пользователя образом.
Существует три альтернативных способа запуска mysqlcheck
:
shell> mysqlcheck [OPTIONS] database [tables] shell> mysqlcheck [OPTIONS] --databases DB1 [DB2 DB3...] shell> mysqlcheck [OPTIONS] --all-databases
Таким образом, утилита может использоваться подобно mysqldump
по отношению
к выбранным базам данных и таблицам.
В сравнении с другими клиентами утилита mysqlcheck
имеет следующую
отличительную особенность: установка поведения по умолчанию, (проверка
таблиц, -с
), может быть изменена путем переименования исполняемого файла
утилиты. Итак, чтобы получить инструмент, восстанавливающий таблицы по
умолчанию, просто скопируйте mysqlcheck
с новым именем, mysqlrepair
, или,
наоборот, сделайте символьную ссылку на mysqlrepair
и обозначьте ее как
mysqlrepair
. Если теперь запустить mysqlrepair
, то утилита по умолчанию
будет восстанавливать таблицы.
Для изменения поведения mysqlcheck
по умолчанию можно использовать
следующие обозначения:
mysqlrepair: Значение по умолчанию будет -r mysqlanalyze: Значение по умолчанию будет -a mysqloptimize: Значение по умолчанию будет -o
Ниже приведены возможные опции для mysqlcheck
. Какие из них поддерживает
ваша версия, можно проверить с помощью команды mysqlcheck --help
.
-A, --all-databases
-
Проверить все базы данных. Аналогична опции
--databases
, если указать все базы данных. -1, --all-in-1
- Вместо выполнения запросов для каждой таблицы в отдельности выполнить все запросы в одном отдельно для каждой таблицы. Имена таблиц будут представлены в виде списка имен, разделенных запятой.
-a, --analyze
- Анализировать данные таблицы.
--auto-repair
- Если проверенная таблица повреждена, автоматически восстановить ее. Исправления будут произведены после проверки всех таблиц, если были обнаружены повреждения.
-#, --debug=...
- Выводит информацию журнала отладки. Часто используется следующий набор параметров: 'd:t:o,filename'
--character-sets-dir=...
- Директория, где находятся установки символов.
-c, --check
- Проверить таблицу на наличие ошибок.
-C, --check-only-changed
- Проверить только таблицы, измененные со времени последней проверки или некорректно закрытые.
--compress
- Использовать сжатие данных в протоколе сервер/клиент.
-?, --help
- Вывести данную вспомогательную информацию и выйти из программы.
-B, --databases
- Проверить несколько баз данных. Обратите внимание на разницу в использовании: в этом случае таблицы не указываются. Все имена аргументов рассматриваются как имена баз данных.
--default-character-set=...
- Установить набор символов по умолчанию.
-F, --fast
- Проверить только базы данных, которые не были закрыты должным образом.
-f, --force
- Продолжать даже при получении ошибки SQL.
-e, --extended
-
При использовании данного параметра совместно с
CHECK TABLE
можно быть на 100 процентов быть уверенным в целостности таблицы, хотя это и займет много времени. Если же использовать этот параметр сREPAIR TABLE
, запустится расширенное восстановление таблицы, которое может потребовать не только длительного времени выполнения, но и привнесет также массу ненужных строк! -h, --host=...
- Подключиться к хосту.
-m, --medium-check
-
Быстрее, чем
--extended-check
, но находит только 99,99 процентов всех ошибок. Для большинства случаев этот вариант вполне подходит. -o, --optimize
- Оптимизировать таблицу.
-p, --password[=...]
- Используемый пароль при подключении к серверу. Если пароль не указан, у пользователя запрашивается пароль с терминала.
-P, --port=...
- Номер порта, используемого для подключения по TCP/IP.
--protocol=(TCP | SOCKET | PIPE | MEMORY)
- Для указания протокола соединения, который надлежит использовать. Новшество в MySQL 4.1.0.
-q, --quick
-
При использовании данной опции совместно с
CHECK TABLE
предотвращается сканирование строк для корректировки неправильных связей. Это наиболее быстрый метод проверки. Если же использовать этот параметр сREPAIR TABLE
, программа попытается восстановить только систему индексов. Это наиболее быстрый метод восстановления таблицы. -r, --repair
- Может исправить почти все, за исключением уникальных ключей, имеющих дубликаты.
-s, --silent
- Выводить только сообщения об ошибках.
-S, --socket=...
- Файл сокета, используемый для подсоединения.
--tables
-
Перекрывает опцию
--databases
(-B
). -u, --user=#
- Имя пользователя MySQL, если этот пользователь в данное время не является активным.
-v, --verbose
- Вывести информацию о различных этапах.
-V, --version
- Вывести информацию о версии и выйти из программы.
4.8.5 mysqldump
, Получение дампов данных и структуры таблицы
Данная утилита позволяет получить дамп (``моментальный снимок'') содержимого базы данных или совокупности баз для создания резервной копии или пересылки данных на другой SQL-сервер баз данных (не обязательно MySQL-сервер). Дамп будет содержать набор команд SQL для создания и/или заполнения таблиц.
Если же резервная копия создается на сервере, то вместо описываемой
утилиты следует использовать mysqlhotcopy
. См.раздел See section 4.8.6 mysqlhotcopy
, Копирование баз данных и таблиц MySQL.
shell> mysqldump [OPTIONS] database [tables] или mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...] или mysqldump [OPTIONS] --all-databases [OPTIONS]
Если не указывать имена таблиц или использовать параметры --databases
или
--all-databases
, то будет получен дамп базы данных в целом (соответственно
- всех баз данных).
Перечень опций, поддерживаемых вашей конкретной версией утилиты mysqldump
,
можно получить, выполнив команду mysqldump --help
.
Следует иметь в виду, что утилита mysqldump
, используемая без опций
--quick
или --opt
, перед тем, как сделать дамп результата выборки
информации, загрузит весь результат в память. Это может создать проблемы
при получении дампа большой базы данных.
Учтите, что не следует применять параметры --opt
или -e
, если вы
собираетесь использовать для получения дампа новую копию программы
mysqldump
, а затем воспроизводить его на очень старом MySQL-сервере.
Утилита mysqldump
поддерживает следующие опции:
--add-locks
-
Добавить команды
LOCK TABLES
перед выполнением иUNLOCK TABLE
после выполнения каждого дампа таблицы (для ускорения доступа к MySQL). --add-drop-table
-
Добавить команду
DROP TABLE
перед каждой командойCREATE TABLE
. -A, --all-databases
-
Произвести дамп всех баз данных. Аналогично опции
--databases
с указанием всех баз данных. -a, --all
- Включить все опции создания объектов, специфичные для MySQL.
--allow-keywords
- Разрешить создавать имена столбцов, которые совпадают с ключевыми словами. Отсутствие конфликтов обеспечивается прибавлением имени таблицы в качестве префикса к имени каждого столбца.
-c, --complete-insert
-
Использовать полные команды
INSERT
(с именами столбцов). -C, --compress
- Использовать сжатие всей информации между клиентом и сервером, если они оба поддерживают сжатие.
-B, --databases
-
Выполнить дамп нескольких баз данных. Обратите внимание на разницу в
использовании: в этом случае таблицы не указываются. Все имена аргументов
рассматриваются как имена баз данных. Оператор
USE db_name;
включается в вывод перед каждой новой базой данных. --delayed
-
Использовать команду
INSERT DELAYED
при вставке строк. -e, --extended-insert
-
Использовать команду
INSERT
с новым многострочным синтаксисом (повышает компактность и быстродействие операторов ввода). -#, --debug[=option_string]
- Отслеживать прохождение программы (для отладки).
--help
- Вывести справочную информацию и выйти из программы.
--fields-terminated-by=...
--fields-enclosed-by=...
--fields-optionally-enclosed-by=...
--fields-escaped-by=...
--lines-terminated-by=...
-
Эти опции используются совместно с параметром
-T
и имеют то же самое значение, что и соответствующие операторы дляLOAD DATA INFILE
. См. раздел See section 6.4.9 Синтаксис оператораLOAD DATA INFILE
. -F, --flush-logs
- Записать на диск данные системного журнала из буфера MySQL-сервера перед началом выполнения дампа.
-f, --force,
- Продолжать даже при получении ошибки SQL при выполнении дампа таблицы.
-h, --host=..
-
Выполнить дамп данных MySQL сервера на указанном хосте. Значение хоста по
умолчанию -
localhost
. -l, --lock-tables.
-
Заблокировать все таблицы перед началом выполнения дампа. Таблицы
блокируются оператором
READ LOCAL
, чтобы разрешить параллельные записи дляMyISAM
-таблиц. Следует отметить, что при выполнении дампа совокупности баз данных опция--lock-tables
блокирует таблицы каждой базы по отдельности. Таким образом, использование этого параметра не гарантирует, что таблицы будут логически непротиворечивы в пределах этих баз данных. В различных базах данных при выполнении дампа таблицы могут находиться в совершенно разных состояниях. -K, --disable-keys
-
Добавляет выражение
/*!40000 ALTER TABLE tb_name DISABLE KEYS */;
и/*!40000 ALTER TABLE tb_name ENABLE KEYS */;
в выводе результата. Это ускорит загрузку данных на сервер MySQL 4.0, так как индексы создаются после внесения всех данных. -n, --no-create-db
-
В выводе результата выражение
CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;
будет отсутствовать. Данная строка будет добавлена в любом случае при использовании опций--databases
или--all-databases
. -t, --no-create-info
-
Не записывать информацию о создании таблицы (команда
CREATE TABLE
). -d, --no-data
- Не записывать информацию из строк таблицы. Это очень полезно для получения дампа структуры таблицы!
--opt
-
То же, что и
--quick --add-drop-table --add-locks --extended-insert --lock-tables
. Должно дать наиболее быстрый дамп для чтения на MySQL-сервере. -pyour_pass, --password[=your_pass]
-
Используемый пароль при подключении к серверу. Если аргумент
=your_pass
не введен,mysqldump
предложит ввести пароль. -P port_num, --port=port_num
- Номер порта TCP/IP, используемого для подключения к хосту.
--protocol=(TCP | SOCKET | PIPE | MEMORY)
- Для указания протокола соединения, который надлежит использовать. Новшество в MySQL 4.1.0.
-q, --quick
-
Выводить дамп непосредственно на стандартный вывод
stdout
без буферизации запроса. Для этого используется функцияmysql_use_result()
. -Q, --quote-names
- Взять в кавычки имена таблиц и столбцов без символов ``'.
-r, --result-file=...
- Прямой вывод указанного файла. Этот опцию следует использовать в MS DOS, так как она предотвращает преобразование символа новой строки '\n' в последовательность '\n\r' (новая строка + возврат каретки).
--single-transaction
-
Данная опция выдает SQL-команду
BEGIN
перед выполнением дампа данных с сервера. Наиболее часто используется сInnoDB
-таблицамии и уровнем изоляции транзакцийREAD_COMMITTED
, так как именно в этом режиме можно получить дамп с непротиворечивым состоянием базы данных после выполнения командыBEGIN
без блокирования каких-либо приложений. Используя эту опцию, необходимо помнить, что при выполнении дампа только транзакционные таблицы будут находиться в непротиворечивом состоянии, т.е. некоторыеMyISAM
- илиHEAP
-таблицы при использовании данной опции могут все же изменить свое состояние. Опция--single-transaction
добавлена в версии 4.0.2. Она является взаимоисключающей по отношению к опции--lock-tables
, так как командаLOCK TABLES
уже принимает открытую транзакцию. -S /path/to/socket, --socket=/path/to/socket
-
Файл сокета для подсоединения к
localhost
(значение хоста по умолчанию). --tables
- Перекрывает параметр --databases (-B).
-T, --tab=path-to-some-directory
-
Для каждой заданной таблицы создает файл a `table_name.sql', содержащий
SQL
CREATE
команды для создания таблицы, и файл `table_name.txt' с данными таблицы. Файл `.txt' имеет формат в соответствии с параметрами--fields-xxx
и--lines--xxx
. Примечание: Этот параметр работает только при условии, что утилитаmysqldump
запущена на том же компьютере, что и демонmysqld
, причем пользователь/группа, запустившие данный потокmysqld
(обычно это пользовательmysql
и группаmysql
), должны иметь право создавать/записывать файл по указанному адресу. -u user_name, --user=user_name
- Имя пользователя MySQL-сервера, используемое при подключении к серверу. Значением по умолчанию является имя пользователя Unix.
-O var=option, --set-variable var=option
-
Установить значения переменных. Доступные для использования переменные
перечислены ниже. В MySQL 4.0 просто используйте
--var=option
. -v, --verbose
- Расширенный режим вывода. Вывод более детальной информации о работе программы.
-V, --version
- Вывести информацию о версии и выйти из программы.
-w, --where='where-condition'
-
Выполнить дамп только выбранных записей. Обратите внимание, что кавычки
обязательны.
"--where=user='jimf'" "-wuserid>1" "-wuserid<1"
-X, --xml
- Представляет дамп базы данных в виде XML.
-x, --first-slave
- Блокирует все таблицы во всех базах данных.
-O net_buffer_length=#, where # < 16M
-
При создании многострочных операторов ввода (как и в случаях применения
параметров
--extended-insert
или--opt
) утилитаmysqldump
будет создавать строки длиной вплоть до указанной вnet_buffer_length
. При увеличении значения этой переменной необходимо также убедиться в том, что в MySQL-сервере для переменнойmax_allowed_packet
указано значение больше, чем величинаnet_buffer_length
.
Чаще всего утилита mysqldump
используется для получения резервной копии
всех баз данных. See section 4.4.1 Резервное копирование баз данных.
mysqldump --opt database > backup-file.sql
Можно, наоборот, прочитать этот файл на MySQL-сервере посредством команды:
mysql database < backup-file.sql
или
mysql -e "source /patch-to-backup/backup-file.sql" database
Данная утилита достаточно часто используется и для переноса информации из базы данных на другой MySQL-сервер:
mysqldump --opt database | mysql --host=remote-host -C database
Вполне возможно получить дамп нескольких баз данных с помощью одной команды:
mysqldump --databases database1 [database2 ...] > my_databases.sql
Если необходим дамп всех баз данных, можно использовать:
mysqldump --all-databases > all_databases.sql
4.8.6 mysqlhotcopy
, Копирование баз данных и таблиц MySQL
Утилита mysqlhotcopy
представляет собой Perl-сценарий, использующий
SQL-команды LOCK TABLES
, FLUSH TABLES
и Unix-утилиты cp
или scp
для
быстрого получения резервной копии базы данных. Пожалуй, это наиболее
быстрый способ копирования баз данных или таблиц, но он
может работать только на том же компьютере, где расположены каталоги
копируемой базы данных.
mysqlhotcopy db_name [/path/to/new_directory] mysqlhotcopy db_name_1 ... db_name_n /path/to/new_directory mysqlhotcopy db_name./regex/
Утилита mysqlhotcopy
поддерживает следующие опции:
-?, --help
- Показать окно справки и выйти из программы.
-u, --user=#
- Имя пользователя для входа в базу данных.
-p, --password=#
- Используемый пароль при подсоединении к серверу.
-P, --port=#
- Номер порта, используемого для подсоединения к локальному серверу.
-S, --socket=#
- Номер сокета, используемого для подсоединения к локальному серверу.
--allowold
- Не делать прерывания, если объект уже существует (переименовать в it_old).
--keepold
- Не удалять предыдущий результат (только что переименованный) после выполнения команды.
--noindices
-
Не включать обширные индексные файлы в копию, чтобы сделать дубликат
меньше по размеру и более быстрым. Индексы можно реконструировать позже с
помощью команды
myisamchk -rq
. --method=#
-
Метод копирования (
cp
илиscp
). -q, --quiet
- Выводить только сообщения об ошибках.
--debug
- Разрешить отладку.
-n, --dryrun
- Сообщать о действиях без их выполнения.
--regexp=#
- Копировать все базы данных с именами, встречающимися в функции regexp.
--suffix=#
- Суффикс для имен скопированных баз данных.
--checkpoint=#
- Внести проверочную запись в предусмотренную таблицу базы данных.
--flushlog
- Записать на диск данные журналов из буфера, как только все таблицы заблокируются.
--tmpdir=#
- Временная директория (вместо `/tmp').
Более полное описание данного сценария можно посмотреть в документации по языку программирования Perl.
Сценарий mysqlhotcopy
берет информацию для групп [client]
и [mysqlhotcopy]
из файлов опций.
Для выполнения программы mysqlhotcopy
необходимы доступ для записи в
директорию, куда будет помещена копия, и привилегия выполнения команды
SELECT
для копируемых таблиц и команды RELOAD
для MySQL-сервера (чтобы
выполнить FLUSH TABLES
).
4.8.7 mysqlimport
, импорт данных из текстовых файлов
Утилита mysqlimport
обеспечивает интерфейс командной строки для
SQL-оператора LOAD DATA INFILE
. Большинство параметров mysqlimport
полностью соответствует аналогичным параметрам для оператора LOAD DATA
INFILE
. See section 6.4.9 Синтаксис оператора LOAD DATA INFILE
.
Утилита mysqlimport
вызывается следующим образом:
shell> mysqlimport [параметры] database textfile1 [textfile2 ...]
Для каждого текстового файла, указанного в командной строке, mysqlimport
удаляет расширение в каждом имени файла и использует его, чтобы
определить, в какую таблицу занести содержимое. Например, файлы с именами
`patient.txt', `patient.text' и `patient' должны быть все занесены в таблицу с
именем `patient'.
Утилита mysqlimport
поддерживает следующие опции:
-c, --columns=...
-
Эта опция принимает в качестве аргумента список разделенных запятыми имен
полей. Данный список полей используется для создания соответствующей
команды
LOAD DATA INFILE
, которая затем посылается в MySQL. See section 6.4.9 Синтаксис оператораLOAD DATA INFILE
. -C, --compress
- Использовать компрессию в связи между клиентом и сервером, если они оба поддерживают сжатие.
-#, --debug[=option_string]
- Отслеживать прохождение программы (для отладки).
-d, --delete
- Удалить данные из таблицы перед импортированием текстового файла.
--fields-terminated-by=...
--fields-enclosed-by=...
--fields-optionally-enclosed-by=...
--fields-escaped-by=...
--lines-terminated-by=...
-
Эти опции аналогичны соответствующим операторам для
LOAD DATA INFILE
. See section 6.4.9 Синтаксис оператораLOAD DATA INFILE
. -f, --force
-
Игнорировать ошибки. Например, если таблица для текстового файла не
существует, продолжать обработку остающихся файлов. Без параметра
--force
утилитаmysqlimport
прекращает работу при отсутствии таблицы. --help
- Вывести справочную информацию и выйти из программы.
-h host_name, --host=host_name
-
Импортировать данные в MySQL-сервер на указанном хосте. Значение хоста по
умолчанию -
localhost
. -i, --ignore
-
См. описание для параметра
--replace
. -l, --lock-tables
- Заблокировать все таблицы для записи перед обработкой любых текстовых файлов. Это обеспечивает синхронизацию всех таблиц на сервере.
-L, --local
-
Читать входящие файлы из клиента. По умолчанию предполагается, что
текстовые файлы расположены на сервере при подсоединении к
localhost
(значение хоста по умолчанию). -pyour_pass, --password[=your_pass]
-
Используемый пароль при подключении к серверу. Если аргумент
=your_pass
не введен,mysqlimport
предложит ввести пароль. -P port_num, --port=port_num
- Номер порта TCP/IP, используемого для подсоединения к хосту.
--protocol=(TCP | SOCKET | PIPE | MEMORY)
- Для указания протокола соединения, который надлежит использовать. Новшество в MySQL 4.1.0.
-r, --replace
-
Опции
--replace
и--ignore
управляют обработкой поступающих на вход записей, которые дублируют имеющиеся записи по значениям уникальных ключей. Если задано значение--replace
, новые строки заменяют существующие с тем же самым значением уникального ключа. Если задано значение--ignore
, входные строки, которые дублируют существующую строку по значению уникального ключа, пропускаются. Если же ни одна из опций не задана, то при обнаружении ключа-дубликата возникает ошибка и остаток текстового файла игнорируется. -s, --silent
- Режим молчания. Выводить только сообщения об ошибках.
-S /path/to/socket, --socket=/path/to/socket
-
Файл сокета для подсоединения к
localhost
(значение хоста по умолчанию). -u user_name, --user=user_name
- Имя пользователя MySQL-сервера, используемое при подсоединении к серверу. Значением по умолчанию является имя для входа в Unix.
-v, --verbose
- Расширенный режим вывода. Вывод более детальной информации о работе программы.
-V, --version
- Вывести информацию о версии и выйти из программы.
Ниже приведен пример листинга программы, использующей утилиту mysqlimport
:
$ mysql --version mysql Ver 9.33 Distrib 3.22.25, for pc-linux-gnu (i686) $ uname -a Linux xxx.com 2.2.5-15 #1 Mon Apr 19 22:21:09 EDT 1999 i586 unknown $ mysql -e 'CREATE TABLE imptest(id INT, n VARCHAR(30))' test $ ed a 100 Max Sydow 101 Count Dracula . w imptest.txt 32 q $ od -c imptest.txt 0000000 1 0 0 \t M a x S y d o w \n 1 0 0000020 1 \t C o u n t D r a c u l a \n 0000040 $ mysqlimport --local test imptest.txt test.imptest: Records: 2 Deleted: 0 Skipped: 0 Warnings: 0 $ mysql -e 'SELECT * FROM imptest' test +------+---------------+ | id | n | +------+---------------+ | 100 | Max Sydow | | 101 | Count Dracula | +------+---------------+
4.8.8 mysqlshow
, просмотр баз данных, таблиц и столбцов
Утилита mysqlshow
позволяет кратко ознакомиться с существующими базами
данных, их таблицами и столбцами таблиц.
Аналогичную информацию можно получить с помощью программы mysql
, используя
команду SHOW
. See section 4.5.6 Синтаксис команды SHOW
.
Утилита mysqlshow
вызывается следующим образом:
shell> mysqlshow [ПАРАМЕТРЫ] [database [table [column]]]
- Если имя базы данных не указано, то выдается список всех существующих баз данных.
- Если не указана таблица - показываются все таблицы, найденные в этой базе данных
- Если не задан столбец - показываются все найденные в таблице столбцы и представленные в виде столбцов данные.
Следует отметить, что в более новых версиях MySQL пользователь может просмотреть только те базы/таблицы/столбцы, для которых у него имеются соответствующие привилегии.
Если последний аргумент содержит в себе шаблонные символы (*
, ?
,
%
или _
) процессора или SQL, то будут представлены только данные,
совпадающие с шаблоном. Если имя базы данных содержит подчеркивание, то оно должно быть
экранировано обратным слешом (некоторые оболочки в Unix востребуют два обратных
слеша) для того, чтобы получить корректные имена. `*' корвертируются в
`%' и `?' - в `_'.
Это может вызвать путаницу при попытке просмотреть
столбцы таблицы с символом _
, так как в таком случае mysqlshow
покажет только имена таблиц, совпадающие с шаблоном. Ситуацию можно легко
исправить добавлением дополнительного символа %
в конец командной строки
(как отдельного аргумента).
4.8.9 mysql_config
, Получение опций компиляции для компиляции клиентских программ
mysql_config
дает полезную информацию о том, как
компилировать ваши клиентские программы.
mysql_config
поддерживает такие опции:
--cflags
- Опции компилятора для поиска включаемых файлов
--libs
- Библиотеки и опции, необходимые для линкования с клиентской библиотекой.
--socket
- Имя сокета по умолчанию, определенное, когда конфигурировался MySQL.
--port
- Номер порта по умолчанию, определенный, когда конфигурировался MySQL.
--version
- Номер версии и версия для поставки MySQL.
--libmysqld-libs
- Библиотеки и опции, необходимые для линкования с библиотекой встраиваемого сервера.
Если вы выполняете mysql_config
без каких-либо параметров, вы получите
все опции, которые он поддерживает плюс значение этих опций:
shell> mysql_config sage: /usr/local/mysql/bin/mysql_config [OPTIONS] Options: --cflags [-I'/usr/local/mysql/include/mysql'] --libs [-L'/usr/local/mysql/lib/mysql' -lmysqlclient -lz -lcrypt -lnsl -lm -L/usr/lib -lssl -lcrypto] --socket [/tmp/mysql.sock] --port [3306] --version [4.0.8-gamma] --libmysqld-libs [ -L'/usr/local/mysql/lib/mysql' -lmysqld -lpthread -lz -lcrypt -lnsl -lm -lpthread -lrt]
Вы можете это использовать, чтобы скопмилировать клиента MySQL таким образом:
CFG=/usr/local/mysql/bin/mysql_config sh -c "gcc -o progname `$CFG --cflags` progname.c `$CFG --libs`"
4.8.10 perror
, разъяснение кодов ошибок
Для большинства системных ошибок, помимо внутреннего текстового сообщения
MySQL, можно также выводить номер кода системной ошибки в одном из
следующих стилей: message ... (errno: #)
или message ... (Errcode: #)
.
Выяснить, что данный код ошибки означает, можно либо путем изучения
документации на данную систему, либо воспользовавшись возможностями
утилиты perror
.
perror выводит описание кода системной ошибки или код ошибки обработчика
таблиц MyISAM
/ISAM
.
perror
вызывается следующим образом:
shell> perror [ПАРАМЕТРЫ] [ERRORCODE [ERRORCODE...]]
Пример:
shell> perror 13 64 Error code 13: Доступ запрещен Error code 64: Компьютер не находится в сети
Следует учитывать, что сообщения об ошибках в большинстве своем являются системно-зависимыми!
4.8.11 Как запускать SQL-команды из текстового файла
Обычно клиент mysql
используется в интерактивном режиме, например,
следующим образом:
shell> mysql database
Однако вполне можно поместить SQL команды в текстовый файл и указать mysql
считывать входные данные из этого файла. Для этого необходимо создать
текстовый файл text_file
, содержащий команды, которые предстоит выполнить.
Затем запускаем mysql
как показано ниже:
shell> mysql database < text_file
Можно также запустить текстовый файл с командой USE db_name
. В этом случае
указывать имя базы данных в командной строке не обязательно:
shell> mysql < text_file
Если программа
mysql уже работает, можно запустить файл с SQL-сценарием,
используя команду source
:
mysql> source filename;
Более подробная информация по пакетному режиму работы находится в разделе
See section 3.6 Использование mysql
в пакетном режиме.
4.9 Файлы журналов MySQL
В MySQL имеется несколько журналов, позволяющих узнать, что происходит
внутри mysqld
:
Журнал | Описание |
Журнал ошибок | В нем хранятся ошибки запуска, работы или завершения работы mysqld .
|
Журнал isam | В нем хранится информация обо всех изменениях таблиц ISAM . Используется только при отладке кода isam.
|
Общий журнал запросов | В нем хранится информация об установленных соединениях и выполненных запросах. |
Журнал обновлений log | В нем хранятся все команды, меняющие данные; в скором времени выйдет из употребления |
Бинарный журнал обновлений | В нем хранятся все меняющие что-либо команды. Используется для репликации |
Журнал медленных запросов | В нем хранятся все запросы, на выполнение которых ушло больше времени, чем указано в переменной long_query_time (или запросы, не использовавшие индексов).
|
Все файлы журналов хранятся в каталоге с данными mysqld
. С помощью команды
FLUSH LOGS
можно заставить mysqld
открыть файлы журналов снова (или - в
некоторых случаях - переключиться на новый файл). See section 4.5.3 Синтаксис команды FLUSH
.
4.9.1 Журнал ошибок
Журнал ошибок содержит информацию о том, когда запускается и останавливается mysqld, а также все критические ошибки, обнаруженные в процессе работы.
В нем содержится информация о запуске и завершении работы mysqld
, а также
обо всех серьезных ошибках, возникших во время работы. Если произойдет
неожиданное аварийное завершение работы, и safe_mysqld
придется
перезапустить mysqld
, safe_mysqld
внесет в этот файл соответствующую
запись. Кроме того, в этот журнал заносится предупреждение в том случае,
если mysqld
обнаружит таблицу, нуждающуюся в автоматической проверке или
исправлении.
Все ошибки mysqld
записывает в stderr
, который сценарий safe_mysqld
перенаправляет в файл с именем 'hostname'.err
(в Windows mysqld
сохраняет
его в каталоге `\mysql\data\mysql.err').
В некоторых ОС в журнал включается распечатка части стека погибшего
mysqld
. С помощью этой информации можно определить причину сбоя (see section D.1.4 Использование трассировки стека).
Начиная с MySQL 4.0.10 можно указать, где именно mysqld должен сохранять журнал
ошибок, с помощью опции --log-error[=filename]
. Если имя файла не задается,
то тогда mysqld будет использовать mysql-data-dir/'hostname'.err
на Unix
и `\mysql\data\mysql.err' на windows.
Если вы выполняете FLUSH LOGS
старый файл будет сохранен с префиксом
--old
и mysqld
создаст новый пустой журнал.
На старых версиях MySQL журнал ошибок велся скриптом mysqld_safe, который перенаправлял вывод в
файл 'hostname'.err
. В старых версиях можно было изменить имя этого файла опцией
--err-log=filename
.
Если вы не указываете --log-error
или используете опцию --console
,
то ошибки будут выводиться на stderr (на терминал).
На Windows вывод всегда пишется в .err
-файл если --console
не была указана.
4.9.2 Общий журнал запросов
Если вы хотите знать обо всем, что происходит с mysqld
, нужно запустить
систему с ключом --log[=file]
. После этого информация обо всех соединениях
и запросах будет записываться в файл журнала (по умолчанию ему дается имя
'hostname'.log
). Этот журнал может оказаться полезным, если вы
подозреваете наличие ошибки в клиентском ПО и хотите выяснить, что, по
мнению mysqld
, клиент передал базе.
Старые версии скрипта mysql.server
(с MySQL 3.23.4 по 3.23.8)
передавали safe_mysqld
опцию --log
(включить общий журнал запросов).
Если вам нужна большая производительность при запуске MySQL в промышленной эксплуатации,
вы можете удалить опцию --log
из mysql.server
или поменять ее на
--log-bin
. See section 4.9.4 Бинарный журнал обновлений.
Записи в журнал заносятся по мере получения mysqld
запросов. Порядок их
занесения может отличаться от порядка выполнения команд. В этом и
заключается основное отличие данного журнала от журналов обновлений и
бинарных журналов, в которые информация заносится по мере выполнения
запросов, но до отмены блокировок.
4.9.3 Журнал обновлений (update)
Обратите внимание: журнал обновлений (update) заменен бинарным журналом (binary) (see section 4.9.4 Бинарный журнал обновлений. С этим журналом можно производить те же операции, что и с журналом обновлений.
При запуске с ключом --log-update[=file_name]
mysqld
создает журнал, в
который заносятся все команды SQL, обновляющие данные. Если имя файла не
задано, по умолчанию ему присваивается имя хоста. Если файлу присвоено
имя, не содержащее пути доступа к нему, этот файл сохраняется в каталоге с
данными. Если у имени `file_name' нет расширения, mysqld
даст файлу примерно
такое имя: `file_name.###', где ###
- номер, увеличивающийся при каждом
выполнении команд mysqladmin refresh
, mysqladmin flush-logs
, FLUSH LOGS
или при перезапуске сервера.
Обратите внимание: чтобы вышеописанная схема могла работать, нельзя самостоятельно создавать файлы с тем же именем, что и у журнала обновлений, а также с некоторыми расширениями, которые могут быть восприняты как номер, в каталоге, использующемся для хранения этого журнала!
При запуске с ключами --log
или -l
mysqld
создает общий журнал в файле с
именем `hostname.log', причем перезапуски и обновления не приводят к
созданию нового файла журнала (хотя существующий при таких операциях
закрывается и затем открывается вновь). В таком случае скопировать его (в
Unix) можно так:
mv hostname.log hostname-old.log mysqladmin flush-logs cp hostname-old.log to-backup-directory rm hostname-old.log
Журнал обновлений работает избирательно - в него попадают только те
команды, которые действительно обновляют данные. Команда UPDATE
или
DELETE
, выражение WHERE
которой не находит совпадающих строк, в журнал не
заносится - как и команды UPDATE
, присваивающие столбцам те же значения,
которые у них были до ``обновления''.
Запись в журнал осуществляется сразу по завершении работы запроса, но до того, как будут сняты блокировки. Таким образом обеспечивается уверенность в том, что журнал ведется именно в порядке выполнения запросов.
При желании обновить базу в соответствии с данными журналов обновлений можно воспользоваться следующей командой (при условии, что имена файлов журналов соответствуют форме `file_name.###'):
shell> ls -1 -t -r file_name.[0-9]* | xargs cat | mysql
ls
расставляет все файлы журналов в правильном порядке.
Эта возможность может пригодиться в случае, если возникнет необходимость (в результате серьезного сбоя) привести базу в соответствие с резервной копией и затем повторить все обновления, произошедшие с момента создания копии и до сбоя.
4.9.4 Бинарный журнал обновлений
Бинарный журнал обновлений в скором времени должен полностью заменить журнал обновлений, так что мы рекомендуем вам как можно скорее перейти на его использование!
Бинарный журнал содержит всю информацию, имеющуюся в журнале обновлений, в более эффективном формате. В нем имеется информация и о времени выполнения каждого обновляющего базу запроса. В нем не содержится информации о запросах, которые не изменяют данные. Если вам нужно журналировать все запросы (например для выявления проблемного запроса), вам следует использовать общий журнал запросов. See section 4.9.2 Общий журнал запросов.
Бинарный журнал используется и при репликации подчиненного сервера (slave) с головного (master) (see section 4.10 Репликация в MySQL).
При запуске с ключом --log-bin[=file_name]
mysqld
создает файл журнала, в
который вносятся данные обо всех обновляющих данные командах SQL. Если имя
файла не задано, по умолчанию ему дается имя хоста с окончанием -bin
. Если
файлу присвоено имя, не содержащее пути доступа к нему, этот файл
сохраняется в каталоге данных.
При вводе расширения в имя файла (например: --log-bin=filename.extension
)
это расширение удаляется без предупреждения.
К имени файла бинарного журнала программа mysqld
прибавляет специальное
расширение - номер, увеличивающийся при каждом выполнении команд
mysqladmin refresh
, mysqladmin flush-logs
, FLUSH LOGS
или перезапуске
сервера. При достижении файлом журнала максимального размера, заданного в
параметре max_binlog_size
, автоматически создается новый. Все неактивные
файлы бинарных журналов можно удалить командой RESET MASTER
(see section 4.5.4 Синтаксис команды RESET
.
На выбор данных, записываемых в журнал, влияют следующие настройки mysqld
:
Опция | Описание |
binlog-do-db=database_name | Указывает головному серверу что он должен журналировать обновления в двоичный журнал если текущая (т.е. выбранная) база данных - это 'database_name'. Остальные базы данных, особо не отмеченные, игнорируются. Имейте в виду, что если вы используете эту опцию, то вам следует делать обновления только в этой базе данных. (пример: binlog-do-db=some_database) |
binlog-ignore-db=database_name |
Заставляет master отказаться от занесения в журнал обновлений определенной базы данных (пример: binlog-ignore-db=some_database )
|
Чтобы была возможность определить, какие файлы журналов используются в
данный момент, mysqld
создает и индексный файл, содержащий имена всех
находящихся в работе файлов. По умолчанию ему присваивается то же имя, что
и файлу журнала, но с расширением .index. Имя этого файла можно изменить с
помощью параметра --log-bin-index=[filename]
.
При использовании репликации удалять старые файлы журналов не стоит до тех
пор, пока вы не будете уверены в том, что они никогда не понадобятся ни
одной зависимой базе. Добиться такого результата можно, запуская команду
mysqladmin flush-logs
раз в день и затем удаляя все журналы, созданные
более 3 дней назад.
Работать с файлами бинарного журнала можно с помощью программы
mysqlbinlog
. Обновить MySQL в соответствии с записями в журнале можно так:
shell> mysqlbinlog log-file | mysql -h server_name
С помощью программы mysqlbinlog
можно даже считывать файлы журнала прямо с
удаленного сервера MySQL!
При запуске mysqlbinlog
с ключом --help
на экран выводится дополнительная
информация по работе с этой программой.
При работе с настройками BEGIN [WORK]
или SET AUTOCOMMIT=0
для резервного
копирования нужно использовать бинарный журнал, а не старый журнал
обновлений.
Занесение данных в бинарный журнал происходит сразу по завершении исполнения запроса, но до снятия блокировок. Таким образом обеспечивается уверенность в том, что журнал ведется именно в порядке выполнения запросов.
Updates to non-transactional tables are stored in the binary log immediately after execution.
Обновления нетранзакционных таблиц сохраняются в двоичном журнале немедленно после выполнения.
Все обновления (UPDATE
, DELETE
или INSERT
), изменяющие данные в транзакционных
таблицах (например, BDB-таблицу) находятся в кэше до вызова COMMIT
. В этот момент mysqld
пишет
всю транзакцию целиком в двоичный журнал перед тем, как выполнить COMMIT
.
Каждый поток при запуске будет создавать буффер размером binlog_cache_size
для буферизации запросов.
Если запрос превышает этот размер, тогда поток откроет временный файл для сохранения транзакции. Временный
файл будет удален при выходе потока.
При
запуске каждого потока создается буфер запросов, объем которого
соответствует значению параметра binlog_cache_size
. Если запрос не
помещается в буфере, поток создаст временный файл для кэша. Временный файл
удаляется по завершении работы потока.
Параметр max_binlog_cache_size
(по умолчанию 4Гб) позволяет ограничить
общий объем памяти, используемой для кэширования мультитранзакционного запроса.
Если транзакция больше этого - будет произведен откат.
При использовании журнала обновлений или бинарного журнала параллельные
операции вставки будут преобразованы в нормальные операции вставки в командах CREATE
... SELECT
и INSERT ... SELECT
. Это сделано специально - для того, чтобы
обеспечить возможность создания точной копии таблиц путем объединения
резервной копии с журналом.
4.9.5 Журнал медленных запросов
При запуске с параметром --log-slow-queries[=file_name]
mysqld
создает
файл журнала, в котором сохраняются данные обо всех командах SQL, на
выполнение которых ушло больше времени, чем указано в значении параметра
long_query_time
. Время, уходящее на первоначальную блокировку таблиц, не
включается во время исполнения запроса.
Занесение данных в журнал происходит сразу по завершении исполнения запроса и снятия блокировок. Таким образом, порядок расположения записей может отличаться от порядка выполнения запросов.
Если имя файла не задано, по умолчанию ему дается имя хоста с окончанием
-slow.log
. Если файлу присвоено имя, не содержащее пути доступа к нему,
этот файл сохраняется в каталоге с данными.
Этот журнал позволяет определить запросы, на выполнение которых ушло
слишком много времени, а, значит, и обнаружить основных кандидатов на
оптимизацию. Конечно, при достижении журналом значительного объема эта
задача усложняется. В таком случае журнал можно пропустить через команду
mysqldumpslow
и получить краткий отчет о запросах, попавших в список.
При использовании ключа --log-long-format
на экран выводятся и запросы, не
работающие с индексами (see section 4.1.1 Параметры командной строки mysqld
).
4.9.6 Обслуживание файлов журналов
В MySQL предусмотрено наличие нескольких файлов журналов, позволяющих следить за всеми аспектами работы системы (see section 4.9 Файлы журналов MySQL). Правда, иногда приходится проверять, не занимают ли журналы лишнего места, и удалять ненужные.
При работе с журналами MySQL, вам, вероятнее всего, понадобится удалять их или создавать их резервные копии, и указывать MySQL записывать данные журналов в новые файлы (see section 4.4.1 Резервное копирование баз данных).
В системе Linux (Red Hat
) для этого можно использовать сценарий
mysql-log-rotate
. При установке MySQL с дистрибутива RPM этот сценарий
устанавливается автоматически. Обратите внимание: использовать журнал для
репликации необходимо с максимальной аккуратностью!
В других ОС вы можете самостоятельно создать небольшой сценарий для
обработки журналов, запускаемый из cron
.
Заставить MySQL создать новый файл журнала можно с помощью команды
mysqladmin flush-logs
или SQL-команды FLUSH LOGS
. При работе с MySQL
версии 3.21 пользоваться можно только командой mysqladmin refresh
.
Эта команда выполняет следующие действия:
-
Если используется стандартный журнал (
--log
) или журнал медленных запросов (--log-slow-queries
), файл журнала (mysql.log
и`hostname`-slow.log
по умолчанию) закрывается и открывается вновь. -
Если используется журнал обновлений (
--log-update
), файл журнала закрывается, после чего создается новый файл с большим номером.
При использовании одного журнала обновлений нужно очистить журналы и перенести их старые файлы в резервную копию. При использовании обычной процедуры ведения журналов для этого нужно выполнить примерно следующую последовательность команд:
shell> cd mysql-data-directory shell> mv mysql.log mysql.old shell> mysqladmin flush-logs
а затем сделать резервную копию файла mysql.old
и удалить его.
4.10 Репликация в MySQL
В этом разделе описаны различные функциональные возможности репликации в MySQL. Он может служить справочником по опциям, используемым при репликации. Здесь будет описан механизм репликации и показано, как реализовывать репликации. В конце раздела мы дадим ответы на некоторые часто задаваемые вопросы, а также описания проблем и способы их решения.
Рекомендуем регулярно посещать наш web-сайт по адресу http://www.mysql.com/ для ознакомления с обновлениями, произошедшими в этом разделе. Механизм репликации постоянно улучшается, и руководство постоянно дополняется самой свежей информацией.
4.10.1 Введение
К числу преимуществ, которые обеспечивает репликация, относится повышение скорости и надежности. Чтобы обеспечить надежность, можно установить две системы и при возникновении проблем с головным сервером переключаться на резервную копию. Для увеличения скорости можно перенаправлять те запросы, которые не обновляют данные, на сервер с копиями. Разумеется, это даст эффект лишь в том случае, если запросы, не обновляющие данные, преобладают, но, как правило, чаще всего так и бывает.
MySQL, начиная с версии 3.23.15, поддерживает односторонний внутренний механизм репликации. Один сервер действует как головной, а другие - как подчиненные. Обратите внимание: один сервер может играть роль головного в одной паре и подчиненного - в другой. Головной сервер содержит двоичный журнал обновлений (see section 4.9.4 Бинарный журнал обновлений) и индексный файл двоичных журналов для протоколирования ротации двоичных журналов. Подчиненный сервер при соединении уведомляет головной о том, в каком состоянии он находится, начиная от последнего обновления, которое было успешно опубликовано на подчиненный сервер. После этого подчиненный сервер принимает обновления, а затем блокируется и ждет, пока головной сервер не сообщит о новых обновлениях.
Обратите внимание: при реплицировании базы данных все обновления этой базы данных должны производиться через головной сервер!
Еще одно преимущество использования механизма репликации заключается в том, что можно иметь "живую" резервную копию системы, выполняя резервное копирование не на головном, а на подчиненном сервере (see section 4.4.1 Резервное копирование баз данных).
4.10.2 Как реализована репликация: обзор
Репликация в MySQL основывается на том, что все изменения базы данных (обновления, удаления и т.д.) протоколируются в двоичном журнале на сервере (see section 4.9.4 Бинарный журнал обновлений), а подчиненный сервер читает сохраненные запросы из двоичного журнала головного сервера и выполняет эти запросы на своей копии данных.
Очень важно понимать, что двоичный журнал - это просто запись, начатая с фиксированного момента времени (с момента, когда вы включаете ведение записей в двоичном журнале). При установке каждого из подчиненных серверов нужно будет скопировать с головного сервера все данные, существовавшие на нем к моменту начала ведения записей в двоичном журнале. Если подчиненный сервер будет запущен с данными, не соответствующими тем, которые содержались на головном сервере к моменту запуска двоичного журнала, на подчиненном сервере может произойти сбой.
В следующей таблице вы найдете информацию о совместимости головных и подчиненных серверов разных версий. С учетом версии 4.0, мы рекомендуем использовать одну и ту же версию на обеих серверах, подчиненном и головном.
Головной | Головной | Головной | Головной | ||
3.23.33 и новее | 4.0.0 | 4.0.1 | 4.0.3 и новее | ||
Подчиненный | 3.23.33 и новее | да | нет | нет | нет |
Подчиненный | 4.0.0 | нет | да | нет | нет |
Подчиненный | 4.0.1 | да | нет | да | нет |
Подчиненный | 4.0.3 и новее | да | нет | нет | да |
Note: MySQL 4.0.2 не рекомендован для репликации.
Начиная с версии 4.0.0 для записи данных на подчиненный сервер можно
использовать команду LOAD DATA FROM MASTER
.
Учтите, что команда LOAD DATA FROM MASTER
в настоящее время работает
только если все таблицы на головном сервере имеют тип MyISAM
, и для них
будет установлена глобальная блокировка чтения, чтобы не допустить никаких
записей во время передачи таблиц от головного сервера к подчиненному.
Данное ограничение носит временный характер. Оно обусловлено тем, что мы
еще не реализовали горячее резервное копирование таблиц без блокировок.
Это ограничение мы снимем для следующих ветвей версии 4.0 - как только
будет реализовано горячее резервное копирование, которое позволит команде
LOAD DATA FROM MASTER
работать без блокирования обновлений на головном
сервере.
Из-за вышеупомянутого ограничения рекомендуется использовать команду LOAD
DATA FROM MASTER
только в тех случаях, если набор данных на головном
сервере относительно невелик или если для головного сервера допустима
длительная блокировка чтения. Скорость выполнения команды LOAD DATA FROM
MASTER
для разных систем может быть различной, поэтому для грубой оценки
времени выполнения команды можно считать, что для передачи 1 Мб данных
требуется 1 секунда. Это приблизительно соответствует случаю, когда и
головной, и подчиненный серверы эквивалентны Pentium с тактовой частотой
700 МГц и связаны сетью с пропускной способностью 100 Мбит/с, а размер
индексного файла равен примерно половине размера файла данных. Разумеется,
такая прикидка дает лишь грубую приближенную оценку и в случае каждой
конкретной системы потребуются свои допущения.
После того как подчиненный сервер будут правильно сконфигурирован и
запущен, он должен легко соединиться с головным сервером и ожидать
обработки обновлений. Если головной сервер завершит работу или подчиненный
сервер потеряет связь с головным, подчиненный сервер будет пытаться
установить соединение каждый раз по истечении интервала времени,
указанного в опции master-connect-retry
(в секундах) до тех пор, пока не
установится подсоединение и не продолжится прослушивание обновлений.
Каждый подчиненный сервер отслеживает события с момента разрыва. Головной сервер не имеет никакой информации о том, сколько существует подчиненных серверов, и какие из них обновлены последними данными в любой момент времени.
В следующем разделе процесс установки головного/подчиненного серверов рассматривается более подробно.
4.10.3 Как настроить репликацию
Здесь кратко описано как настроить полную репликацию вашего MySQL-сервера. Предполагается, что реплицироваться будут все базы данных и репликация ранее не настраивалась. Для того чтобы выполнить указанные здесь действия, вам придется на короткое время остановить головной сервер.
Это самый простой способ установки подчиненного сервера, однако он не единственный. Например, если уже имеется образ головного сервера, на головном сервере уже установлен ID сервера и производятся записи в журнал, подчиненный сервер можно установить, не останавливая головной сервер и даже не устанавливая блокировки обновлений (за дополнительной информацией обращайтесь к разделу See section 4.10.7 Часто задаваемые вопросы по репликации.
Чтобы стать настоящим гуру по репликации в MySQL, советуем сначала изучить, осмыслить и опробовать все команды, упомянутые в разделе See section 4.10.6 SQL-команды, относящиеся к репликации. Необходимо также ознакомиться с опциями запуска репликации из файла `my.cnf' в разделе See section 4.10.5 Опции репликации в файле `my.cnf'.
- Удостоверьтесь, что на головном и подчиненном(ых) серверах установлена свежая версия MySQL. Используйте версию 3.23.29 или выше. В предыдущих релизах применялся другой формат двоичного журнала и содержались ошибки, которые были исправлены в более новых релизах. Большая просьба: пожалуйста, не посылайте сообщения об ошибках, не проверив, присутствует ли эта ошибка в последнем релизе.
-
Установите на головном сервере отдельного пользователя для репликации
с привилегией
FILE
(в версиях MySQL ниже 4.0.2) илиREPLICATION SLAVE
в более новых версиях MySQL. У этого пользователя должно быть также разрешение подсоединяться со всех подчиненных серверов. Если пользователь будет выполнять только репликацию (рекомендуется), то ему не нужно предоставлять какие-либо дополнительные привилегии. Например, чтобы создать пользователя с именемrepl
, который может иметь доступ к головному серверу с любого хоста, можно использовать такую команду:mysql> GRANT FILE ON *.* TO repl@"%" IDENTIFIED BY '<password>'; # головной < 4.0.2
mysql> GRANT REPLICATION SLAVE ON *.* TO repl@"%" IDENTIFIED BY '<password>'; # головной >= 4.0.2
Если вы планируете использоватьLOAD TABLE FROM MASTER
илиLOAD DATA FROM MASTER
(доступные с версии 4.0.0), вам также надо выделить привилегииRELOAD
иSUPER
на головном сервере для вышеуказанного пользователя. -
Если вы используете MyISAM-таблицы, сохраните содержимое и заблокируйте модифицирующие запросы командой
FLUSH TABLES WITH READ LOCK
.mysql> FLUSH TABLES WITH READ LOCK;
и после этого - снимите образ данных на вашем головном сервере. Легче всего сделать это (на Unix), создав при помощи tar архив всей своей директории данных. Точное местоположение директории данных зависит от вашей инсталляции.tar -cvf /tmp/mysql-snapshot.tar /path/to/data-dir
Пользователи Windows для создания архива каталога данных могут использоватьWinZIP
или другую подобную программу. После того как снимок будет или прямо во время этого процесса, узнайте значения: имя текущего двоичного журнала и позицию на головном сервере:mysql > SHOW MASTER STATUS; +---------------+----------+--------------+-------------------------------+ | File | Position | Binlog_do_db | Binlog_ignore_db | +---------------+----------+--------------+-------------------------------+ | mysql-bin.003 | 73 | test,bar | foo,manual,sasha_likes_to_run | +---------------+----------+--------------+-------------------------------+ 1 row in set (0.06 sec)
СтолбецFile
дает имя журнала,Position
дает информацию о смещении в журнале (позиции). В этом примере имя журнала -mysql-bin.003
и смещение -73
. Запишите эти значения - они вам понадобятся чуть позже, когда будете настраивать подчиненный сервер. Когда вы получили образ и сохранили указанную информацию, вы можете снова разрешить запись в таблицы на головном сервере:mysql> UNLOCK TABLES;
Если вы используете таблицы InnoDB, то в идеале было бы хорошо, чтобы вы использовали ПО InnoDB Hot Backup. Она берет целостный снимок без установки каких-либо блокировок на головном сервере, и сохраняет имя журнала и позицию непосредственно в снимке, что позволит в дальнейшем использовать эту информацию на подчиненном сервере. Более подробная информация об этой программе доступна на http://www.innodb.com/hotbackup.php. Без использования этой утилиты, наиболее быстрый способ получить снимок таблиц InnoDB - это остановить головной сервер и скопировать файлы данных, журналы, и файлы определений формата таблицы (`.frm'). Для сохранения текущего имени файла журнала и смещения, вам следует выполнить следующее перед остановкой сервера:mysql> FLUSH TABLES WITH READ LOCK; mysql> SHOW MASTER STATUS;
И затем сохраните имя журнала и смещение из вывода командыSHOW MASTER STATUS
так, как было показано выше. После этого остановите сервер без снятия блокировок с таблиц. Это нужно сделать именно так, чтобы быть уверенным, что сервер остановится именно с тем снимком, который мы сделали:shell> mysqladmin -uroot shutdown
Если головной сервер был ранее запущен без опцииlog-bin
, то значения имени файла журнала и позиции будут пустыми в выводеSHOW MASTER STATUS
. В этом случае, сохраните пустую строку ('') как имя файла журнала и4
как позицию. -
В `my.cnf' на головном сервере добавьте к разделу
[mysqld]
записиlog-bin
иserver-id=уникальный номер
и перезапустите сервер. Очень важно, чтобы номер подчиненного сервера отличался от номера головного сервера. Можно считать, чтоserver-id
играет роль IP-адреса - он уникально идентифицирует сервер среди участников репликации.[mysqld] log-bin server-id=1
-
Добавьте в my.cnf на подчиненном сервере(ах) следующий фрагмент:
server-id=<некоторое уникальное число между 2 и 2^32-1>
заменяя значения в <> значениями, соответствующими вашей системе. Значенияserver-id
должны быть различными на каждом сервере, участвующем в репликации. Если значениеserver-id
не определено, оно будет установлено в 1, если также не определено значениеmaster-host
, оно будет установлено в 2. Обратите внимание, что если значениеserver-id
опущено, то головной сервер будет отказывать в соединении всем подчиненным серверам, а подчиненный сервер - отказывать в соединении головному серверу. Таким образом, опускать установку значенияserver-id
можно лишь в случае резервного копирования с использованием двоичного журнала. -
Когда подчиненный сервер будет работать, заставьте его забыть старую конфигурацию репликации,
если он использовался в репликации раньше:
mysql> RESET SLAVE;
- Скопируйте данные снимка в директорию данных на подчиненном сервере (ах). Удостоверьтесь в правильности привилегий для файлов и каталогов. Пользователь, от имени которого запускается MySQL, должен иметь возможность читать и записывать данные в них так же, как и на головном сервере.
- Перезапустите подчиненный(ые) сервер(ы).
-
Когда подчиненные сервера запустятся, выполните:
mysql> CHANGE MASTER TO MASTER_HOST='<имя хоста головного сервера>', MASTER_USER='<имя пользователя репликации>', MASTER_PASSWORD='<пароль репликации>', MASTER_LOG_FILE='<записанное вами имя журнала>', MASTER_LOG_POS=<записанная вами позиция>;
заменяя значения в <> значениями, соответствующими вашей системе. -
Запустите поток подчиненного сервера:
mysql> SLAVE START;
После выполнения указанных действий подчиненный(ые) сервер(ы) должен(ы) подсоединиться к головному серверу и подгонять свои данные под любые изменения, произошедшие на головном сервере после принятия образа.
Если не установлен идентификатор server
-id для подчиненного сервера, в
журнальный файл регистрации ошибок будет внесена следующая ошибка:
Warning: one should set server_id to a non-0 value if master_host is set. The server will not act as a slave. (Предупреждение: если задан master_host, следует установить server_id в ненулевое значение. Сервер не будет работать как подчиненный сервер.)
Если не установлен идентификатор головного сервера, подчиненные серверы не смогут подключиться к головному серверу.
Если подчиненный сервер по какой-либо причине не может выполнять репликацию, соответствующие сообщения об ошибках можно найти в журнале регистрации ошибок на подчиненном сервере.
После того как подчиненный сервер начнет выполнять репликацию, в той же
директории, где находится журнал регистрации ошибок, появится файл
`master.info'. Файл `master.info' используется подчиненным сервером для
отслеживания того, какие записи двоичных журналов головного сервера
обработаны. Не удаляйте и не редактируйте этот файл, если не уверены в
том, что это необходимо. Даже если такая уверенность есть, все равно лучше
использовать команду CHANGE MASTER TO
.
На данном этапе у вас есть снимок, который вы можете использовать для настройки и установки других подчиненных серверов. Чтобы сделать это, вам надо повторить вышеописанную процедуру в части настройки подчиненного сервера. Вам не нужно создавать еще один снимок головного сервера.
4.10.4 Возможности репликации и известные проблемы
Ниже приводится список поддерживаемых и не поддерживаемых при репликации функций:
-
Реплицирование будет выполнено правильно при использовании значений
AUTO_INCREMENT
,LAST_INSERT_ID()
иTIMESTAMP
. -
Если в обновлениях присутствует функция
RAND()
, реплицирование будет выполнено некорректно. При реплицировании обновлений с функциейRAND()
применяйтеRAND(some_non_rand_expr)
. В качестве аргумента (some_non_rand_expr
- некоторое не случайное выражение) для функцииRAND()
можно, например, использовать функциюUNIX_TIMESTAMP()
. -
На головном и подчиненном серверах следует использовать одинаковый
набор символов (
--default-character-set
). В противном случае могут возникать ошибки дублирующихся ключей на подчиненном сервере, поскольку ключ, который считается уникальным на головном сервере, может не быть таковым при использовании другого набора символов. -
В MySQL 3.23 команда
LOAD DATA INFILE
будет выполнена корректно, если файл во время выполнения обновления будет находиться на головном сервере. КомандаLOAD LOCAL DATA INFILE
будет проигнорирована. В MySQL 4.0 это ограничение не присутствует - все разновидности командыLOAD DATA INFILE
реплицируются правильно. - Запросы на обновление, в которых используются пользовательские переменные, являются не безопасными для репликации (пока).
-
Команды
FLUSH
не записываются в двоичный журнал и поэтому не копируются на подчиненный сервер. Проблем при этом не возникает, поскольку командыFLUSH
ничего не изменяют. Однако это означает, что при непосредственном, без использования оператораGRANT
, обновлении таблиц привилегий MySQL и при последующем реплицировании базы данных привилегийmysql
нужно выполнить командуFLUSH PRIVILEGES
на подчиненных серверах, чтобы новые привилегии вступили в силу. -
Временные таблицы, начиная с версии 3.23.29, реплицируются корректно,
за исключением случая, когда при прекращении работы подчиненного
сервера (не только потока подчиненного сервера) некоторые временные
таблицы остаются открытыми и используются в последующих обновлениях.
Для решения этой проблемы перед прекращением работы подчиненного
сервера выполните команду
SLAVE STOP
, проверьте, чтобы переменнаяSlave_open_temp_tables
содержала значение 0, затем выполнитеmysqladmin shutdown
. Если значение переменнойSlave_open_temp_tables
не 0, перезапустите поток подчиненного сервера при помощи командыSLAVE START
и проверьте, не улучшилась ли ситуация теперь. Эта проблема будет решаться более изящно, но придется подождать MySQL 4.0. В более ранних версиях при использовании временных таблиц репликации не выполняются должным образом - в таких случаях мы рекомендуем либо обновить версию MySQL, либо перед выполнением запросов, использующих временные таблицы, выполнить командуSET SQL_LOG_BIN=0
на своих клиентах. - MySQL поддерживает лишь один головной и много подчиненных серверов. В 4.x будет добавлен алгоритм голосования, обеспечивающий автоматическое изменение головного сервера, если что-либо будет выполняться неправильно при текущем головном сервере. Будут также введены процессы 'агента', которые помогут выполнять распределение нагрузки путем посылки запросов на выборки различным подчиненным серверам.
-
Начиная с версии 3.23.26 стало безопасно соединять серверы
циклическими соединениями головной-подчиненный с включенной опцией
log-slave-updates
. Однако обратите внимание: при таком способе установки многие запросы не будут выполняться корректно, если только в коде вашего клиента не предусмотрена обработка потенциальных проблем, которые могут случаться при обновлениях, происходящих в различной последовательности на различных серверах. Это означает, что если вы сделаете установку следующим образом:A - > B > - C - > A
то такая установка будет работать только в том случае, если выполняются непротиворечивые обновления между таблицами. Другими словами, при вставке данных на серверахA
иC
нельзя вставлять на сервереA
строку, которая может иметь ключ, противоречащий строке, вставляемой на сервереC
. Также нельзя обновлять одинаковые строки на двух серверах, если имеет значение порядок обновлений. Обратите внимание: в версии 3.23.26 изменился формат журнала. Таким образом, если версия подчиненного сервера меньше 3.23.26, сервер не сможет считывать записи из журнала. -
Если запрос на подчиненном сервере вызывает ошибку, поток подчиненного
сервера завершится, и в файле `.err' появится соответствующее сообщение.
После этого нужно будет вручную установить соединение с подчиненным
сервером, исправить причину ошибки (например обращение к
несуществующей таблице) и затем выполнять SQL-команду
SLAVE START
(доступна в версии 3.23.16). При использовании версии 3.23.15 потребуется перезапустить сервер. -
Если соединение с головным сервером прервется, подчиненный сервер
попытается сразу же восстановить его, и затем в случае неудачи будет
повторять попытки через установленное в опции
master-connect-retry
количество секунд (по умолчанию 60). По этой причине безопасно выключить головной сервер и после этого перезапустить его через некоторое время. Подчиненный сервер будет также разрешать проблемы, возникающие при аварийных отключениях электричества в узлах сети. - Завершение работы подчиненного сервера (корректное) также является безопасным, поскольку при этом отслеживаются события начиная от момента остановки сервера. Но в случае некорректного отключения сервера могут возникать проблемы, особенно, если дисковый кэш не был синхронизирован перед ``смертью'' системы. Для того чтобы значительно повысить эффективность своей системы обеспечения отказоустойчивости, целесообразно приобрести хороший UPS (источник бесперебойного питания).
-
Если головной сервер слушает нестандартный порт, это нужно будет
указать также в параметре
master-port
в файле `my.cnf'. -
В версии 3.23.15 все таблицы и базы данных могут быть реплицированы.
Начиная с версии 3.23.16 появилась возможность ограничить репликацию
набором баз данных при помощи директив
replicate-do-db
в файле `my.cnf'; можно также исключить набор баз данных из репликации при помощи директивreplicate-ignore-db
. Обратите внимание,: в версиях MySQL до 3.23.23, имелась ошибка, из-за которой командаLOAD DATA INFILE
выполнялась некорректно, если она применялась к базе данных, исключенной из репликации. -
Начиная с версии 3.23.16 команда
SET SQL_LOG_BIN = 0
будет выключать ведение записей о репликации в журналах (двоичных) на головном сервере, а командаSET SQL_LOG_BIN = 1
- включать такое ведение записей. Для выполнения этих команд нужно иметь привилегиюSUPER
(в MySQL 4.0.2 и выше) илиPROCESS
(в более ранних версиях MySQL). -
Начиная с версии 3.23.19 можно убрать мусор, оставшийся после
неоконченной репликации (если ее выполнение пошло не должным образом),
и начать все сначала, используя команды
FLUSH MASTER
иFLUSH SLAVE
. В версии 3.23.26 эти команды переименованы в RESET MASTER и RESET SLAVE соответственно - чтобы сделать понятным их назначение. Тем не менее, старые вариантыFLUSH
все еще работают - для обеспечения совместимости. -
Начиная с версии 3.23.23 можно заменять головные серверы и
корректировать точку положения в журнале репликации при помощи команды
CHANGE MASTER TO
. -
Начиная с версии 3.23.23 можно при помощи опции
binlog-ignore-db
уведомлять головной сервер о том, что обновления в некоторых базах данных не должны отражаться в двоичном журнале. -
Начиная с версии 3.23.26, можно использовать опцию
replicate-rewrite-db
для уведомления подчиненного сервера о том, что он должен применить обновления базы данных на головном сервере к базе данных с другим именем на подчиненном сервере. -
Начиная с версии 3.23.28 можно использовать команду
PURGE MASTER LOGS TO 'имя-журнала'
, чтобы избавиться от старых журналов без завершения работы подчиненного сервера. Это удалит все журналы до, но не включаяlog-name
. -
Из-за того, что по своей природе таблицы
MyISAM
являются нетранзакционными, может случиться так, что запрос обновит таблицу только частично и возвратит код ошибки. Это может произойти, например, при вставке нескольких строк, одна из которых нарушает ограничение ключа, или в случае, когда длинный запрос обновления ``убивается'' после обновления некоторых строк. Если такое случится на головном сервере, поток подчиненного сервера завершит работу и будет ждать, пока администратор базы данных не примет решение о том, что делать в этом случае (если только код ошибки не является легитимным и в результате выполнения запроса не будет сгенерирована ошибка с тем же кодом). Если такой способ проверки правильности кода ошибки нежелателен, начиная с версии 3.23.47, некоторые (или все) ошибки могут быть замаскированы при помощи опцииslave-skip-errors
. -
Отдельные таблицы могут исключаться из репликации при помощи опции
replicate-do-table
/replicate-ignore-tab
или опцииreplicate-wild-do-table
/replicate-wild-ignore-table
. Однако в настоящее время наличие определенных конструктивных неточностей в некоторых довольно редких случаях может приводить к неожиданным результатам. Протокол репликации явно не уведомляет подчиненный сервер о том, какие таблицы должны быть изменены запросом, поэтому подчиненному серверу требуется анализировать запрос, чтобы узнать это. Чтобы избежать лишнего синтаксического анализа, для которого требуется прерывать выполнение запросов, исключение таблицы в настоящее время реализуется путем посылки запроса к стандартному анализатору MySQL для упрощенного синтаксического анализа. Если анализатор обнаружит, что таблица должна игнорироваться, выполнение запроса будет остановлено и выдано сообщение об успехе. Этот подход несколько неэффективен, при его применении чаще возникают ошибки и, кроме того, имеются две известные ошибки в версии 3.23.49. Первая может возникнуть из-за того, что поскольку анализатор автоматически открывает таблицу при анализе некоторых запросов, игнорируемая таблица должна существовать на подчиненном сервере. Другая ошибка заключается в том, что при частичном обновлении игнорируемой таблицы поток подчиненного сервера не заметит, что таблица должна игнорироваться, и приостановит процесс репликации. Несмотря на то что вышеупомянутые ошибки концептуально очень просто исправить, для этого придется изменить достаточно много кода, что поставит под угрозу состояние стабильности ветви 3.23. Если описанные случаи непосредственно имеют отношение к вашему приложению (а это довольно редкий случай) - используйте опциюslave-skip-errors
, чтобы дать указание серверу продолжать репликации, игнорируя эти ошибки.
4.10.5 Опции репликации в файле `my.cnf'
Для использования репликации рекомендуется MySQL 3.23.33 или выше. С более ранними версиями тоже можно работать, но в них имеются ошибки и отсутствуют некоторые возможности. Если у вас не самая последняя версия MySQL, то в ней может не оказаться некоторых из упомянутых в данном разделе опций. Все опции, появившиеся в ветви 4.0, сопровождаются примечанием, в котором это указано. В противном случае, если интересующая вас опция не присутствует в версии 3.23, но действительно необходима, пожалуйста, замените версию на самую новую ветвь 3.23.
Не следует забывать о том, что ветвь 4.0 все еще находится в стадии альфа-разработки, поэтому некоторые функции могут работать не так гладко, как хотелось бы. Новые возможности, появившиеся в 4.0, рекомендуется использовать так, чтобы в случае возникновения проблемы не нарушилась работа приложения.
Как на головном, так и на подчиненном серверах нужно использовать опцию
server-id
. Она устанавливает уникальный идентификатор репликации. Нужно
выбрать уникальное значение из диапазона от 1 до 2^32-1 для каждого
головного и подчиненного сервера, например: server-id=3
В следующей таблице представлены опции, которые можно использовать для головного сервера.
Опция | Описание |
log-bin=filename |
Указывает местоположение двоичного журнала обновлений, в котором будут вестись
записи. Обратите внимание: если передаваемый параметр имеет расширение
(например log-bin=/mysql/logs/replication.log ), то в случае вызова
команды FLUSH LOGS версии MySQL ниже 3.23.24 не будут правильно работать
во время репликации. Эта проблема устранена в версии 3.23.25. Теперь, если
используется такой способ определения имени журнала, команда FLUSH LOGS
для двоичных журналов будет игнорироваться. Для очистки журнала выполните
команду FLUSH MASTER и не забудьте запустить команду FLUSH SLAVE
на всех подчиненных серверах. В версии 3.23.26 или выше нужно использовать для
этого команды RESET MASTER и RESET SLAVE
Вы можете использовать эту опци. если вы хотите иметь имя, которое будет независимо
от имени хоста (может быть полезно, скажем, если вы переименуете ваш сервер в один прекрасный день).
|
log-bin-index=filename |
Так как пользователь может выполнять
команду FLUSH LOG , нужно знать, какой
журнал является активным в настоящее
время, а также какие журналы
использовались ранее и в какой
последовательности они сменялись. Эта
информация сохранена в индексном файле
двоичного журнала, имя которого по
умолчанию `имя_хоста.index'. Имя и
содержимое данного файла не следует
изменять.
Пример: log-bin-index=db.index
|
sql-bin-update-same |
Если включена данная опция, то при
установке значения переменной SQL_LOG_BIN
это же значение будет автоматически
установлено и для переменной
SQL_LOG_UPDATE , и наоборот.
|
binlog-do-db=database_name |
Указывает головному серверу, что он
должен вести записи об обновлениях в
двоичном журнале, если текущая база
данных - database_name . Все другие базы
данных игнорируются. Обратите внимание:
при использовании этой опции вы должны
быть уверены, что обновления будут
производиться только в текущей базе
данных.
Пример: binlog-do-db=sales
|
binlog-ignore-db=database_name |
Указывает головному серверу, что если
текущая база данных - database_name , то
записи об обновлениях не должны вестись в
двоичном журнале. Обратите внимание: при
использовании этой опции вы должны быть
уверены, что обновления будут
производиться только в текущей базе
данных.
Пример: binlog-ignore-db=accounting
|
В следующей таблице представлены опции, которые можно использовать для подчиненного сервера:
Опция | Описание |
master-host=host |
Имя хоста головного сервера или IP-адрес для
репликации. Если значение этой опции не
установлено, поток подчиненного сервера не будет
запущен. Обратите внимание: установка master-host
будет игнорироваться, если существует корректный
файл `master.info'. Возможно, лучше было бы назвать
эти опции как-нибудь иначе, что-то вроде
bootstrap-master-host , но менять их имена уже
поздно.
Пример: master-host=db-master.mycompany.com
|
master-user=username |
Имя пользователя, которое подчиненный сервер будет
использовать для аутентификации при подсоединении
к головному серверу. Пользователь должен иметь
привилегию FILE . Если пользователь головного
сервера не установлен, будет использовано имя
пользователя test . Если удастся считать значение
из файла `master.info', то оно будет иметь больший
приоритет.
Пример: master-user=scott
|
master-password=password |
Пароль, который будет использоваться при
подсоединении подчиненного сервера к головному
серверу. Если этот пароль не установлен, будет
использоваться пустой пароль. Если удастся считать
значение из файла `master.info,' то оно будет иметь
больший приоритет.
Пример: master-password=tiger
|
master-port=portnumber |
Порт, который слушает головной сервер. Если не он
не установлен, используется откомпилированная
установка MYSQL_PORT . Это должно быть значение
3306 , если оно не было изменено при помощи опций
configure . Если удастся считать значение из файла
`master.info', то оно будет иметь больший приоритет
Пример: master-port=3306
|
master-connect-retry=seconds |
Время ожидания в секундах для потока подчиненного
сервера перед повторением попытки установить связь
с головным сервером в случае прекращения работы
головного сервера или потери связи. По умолчанию
- 60.
Пример: master-connect-retry=60
|
master-ssl |
Доступна для версий выше 4.0.0. Включает SSL для
репликации. Это относительно новая опция, поэтому
применять ее следует осторожно.
Пример: master-ssl
|
master-ssl-key |
Доступна для версий выше 4.0.0. Имя файла-ключа
SSL на головном сервере. Используется только в том
случае, если включена опция master-ssl .
Пример: master-ssl-key=SSL/master-key.pem
|
master-ssl-cert |
Доступна для версий выше 4.0.0. Имя
файла-сертификата SSL. Используется только в том
случае, если включена опция master-ssl .
Пример: master-ssl-key=SSL/master-cert.pem
|
master-info-file=filename |
Местоположение файла, в который записывается
информация о том, где на головном сервере
произошла остановка во время выполнения
репликации. По умолчанию это файл `master.info' в
директории данных. Изменять это местоположение нет
необходимости.
Пример: master-info-file=master.info
|
report-host |
Доступна для версий выше 4.0.0. Имя хоста или
IP-адрес подчиненного сервера, который передается
головному серверу во время регистрации
подчиненного сервера. Может быть выведен командой
SHOW SLAVE HOSTS . Не устанавливайте эту опцию,
если не хотите, чтобы подчиненный сервер
регистрировался на головном сервере. Обратите
внимание: для того, чтобы головной сервер
установил соединение с подчиненным сервером, ему
недостаточно просто получить IP-адрес подчиненного
сервера из соединения. Из-за NAT и других проблем
маршрутизации IP-адрес может быть недопустимым для
подсоединения головного сервера или других хостов
к подчиненному серверу.
Пример: report-host=slave1.mycompany.com
|
report-port | Доступна для версий выше 4.0.0. Порт для соединения с подчиненным сервером, имя хоста или IP-адрес которого были переданы головному серверу при регистрации подчиненного сервера. Порт нужно устанавливать лишь в том случае, когда подчиненный сервер слушает порт, который задан не по умолчанию, или если имеется специальный тоннель от головного сервера или других клиентов к подчиненному серверу. Не используйте эту опцию, если не уверены в своих действиях. |
replicate-do-table=db_name.table_name |
Сообщает подчиненному серверу, что он должен
реплицировать только указанную таблицу. Для
указания более чем одной таблицы директиву следует
использовать несколько раз, по одному разу для
каждой таблицы. В отличие от replicate-do-db ,
данную опцию можно применять для обновлений, в
которых используется несколько баз данных.
Пример: replicate-do-table=some_db.some_table
|
replicate-ignore-table=db_name.table_name |
Указывает подчиненному серверу, что команды, обновляющие эту таблицу,
не должны реплицироваться. Для указания
более чем одной таблицы директиву следует задавать
несколько раз, по одному разу для каждой таблицы.
В отличие от replicate-do-db , данную опцию можно
применять для обновлений, в которых используется
несколько баз данных.
Пример: replicate-ignore-table=db_name.some_table
|
replicate-wild-do-table=db_name.table_name |
Указывает подчиненному серверу, что должны реплицироваться только те
запросы, где хоть одна из таблиц удовлетворяет указанном шаблону. Для указания
более чем одной таблицы директиву следует задавать несколько раз, по одному
разу для каждой таблицы. Данную опцию можно применять для обновлений, в
которых используется несколько баз данных. Пример: при использовании
replicate-wild-do-table=foo%.bar% будут реплицироваться обновления
только таблиц с именами, начинающимися с ``bar'', которые находятся в базах
данных, с именами, начинаются с ``foo''.
Заметьте, что если вы используете replicate-wild-do-table=foo%.% тогда
это правило также распространяется и на CREATE DATABASE и на DROP
DATABASE , т.е. эти два выражения также будут реплицированы если имя базы
данных совпадет с шаблоном ('foo%' в этом примере; это получается из-за
того, что символ % становится шаблонным).
|
replicate-wild-ignore-table=db_name.table_name |
Указывает подчиненному серверу, запросы, где используется одна из перечисленных здесь таблиц,
реплицироваться не должны. Для указания более чем
одной подлежащей игнорированию таблицы директиву
следует задавать несколько раз, по одному разу для
каждой таблицы. Данную опцию можно применять для
обновлений, в которых используется несколько баз
данных. Например, при использовании
replicate-wild-do-table=foo%.bar% не будут
реплицироваться обновления всех таблиц,
начинающихся на ``bar'', в базах данных, имена
которых начинаются на ``foo''.
|
replicate-ignore-db=database_name |
Сообщает подчиненному серверу, что не следует реплицировать ни
один запрос, в котором текущая база данных - database_name . Чтобы
указать более одной базы данных, директиву следует использовать несколько раз,
по одному разу для каждой базы данных.
Вы не должны использовать эту директиву,
если вы используете кросс-табличные обновления, и не хотите чтобы
эти обновления реплицировались.
Основная причина такого поведения заключается в том, что очень трудно
из самой команды понять, должен ли этот запрос реплицироваться или нет.
Например, если вы используете многотабличное удаление или многотабличное обновление
в MySQL 4.x, которое охватывает более чем одну базу данных.
Кроме того, достаточно быстро можно проверить, является ли текущая база данных
соответствующей, т.к. эта проверка выполняется только на момент соединения или смены базы данных.
Если такие обновления необходимо производить, убедитесь, что у вас установлена
версия MySQL 3.23.28 или выше и используйте
replicate-ignore-db=db_name.% .
Пример: replicate-ignore-db=some_db
|
replicate-do-db=database_name |
Сообщает подчиненному серверу, что реплицироваться
должна только указанная база данных. Чтобы указать
более одной базы данных, директиву следует
использовать несколько раз, по одному разу для
каждой базы данных. Заметьте, что не будут реплицироваться
обновления, охватывающие несколько баз данных, такие как
UPDATE some_db.some_table SET foo='bar' при том, что выбрана другая база данных или не выбрана вовсе.
Если такие обновления необходимо производить, убедитесь, что у вас установлена
версия MySQL 3.23.28 или выше и используйте
replicate-wild-do-table=db_name.% .
Пример: replicate-do-db=some_db
|
log-slave-updates | Указывает подчиненному серверу, чтобы тот вел записи об обновлениях, происходящих на подчиненном сервере, в двоичном журнале. По умолчанию эта опция выключена. Ее следует включить, если требуется организовать подчиненные серверы в гирляндную цепь. |
replicate-rewrite-db=from_name->to_name |
Обновления производятся не в подлинную базу
данных, а в базу данных с именем, указанным в
опции.
Пример: replicate-rewrite-db=master_db_name->slave_db_name
|
slave-skip-errors= [err_code1,err_code2,... | all] |
Доступна только в версии 3.23.47 и выше. Сообщает
потоку подчиненного сервера, что он должен
продолжать репликацию, если запрос возвращает
ошибку, указанную в списке. Обычно при
возникновении ошибки выполнение реплицирование
прекращается, чтобы пользователь мог вручную
исправить несоответствия в данных. Не используйте
данную опцию, если вы до конца не разобрались в
причинах возникновения ошибок. Если не было
допущено ошибок при установке репликации, нет
ошибок в клиентских программах и нет никаких
ошибок непосредственно в MySQL, то прекращения
работы из-за ошибки происходить не должно.
Неразборчивое применение данной опции может
привести к тому, что подчиненный сервер окажется
безнадежно не синхронизированным с головным
сервером, и вы будете тщетно ломать себе голову
над тем, каким образом это случилось. Код ошибок
можно получить в сообщениях об ошибках в журнале
ошибок и в выводе команды SHOW SLAVE STATUS .
Полный список сообщений об ошибках можно найти в
файле исходного дистрибутива
`Docs/mysqld_error.txt'. Можно также (но не нужно)
использовать значение all (хотя этого делать
настоятельно не рекомендуется) - тогда будут
игнорироваться все сообщения об ошибках и за
процессом переброски данных наблюдения не будет.
Само собой разумеется, при использовании этой
опции целостность данных ставится под угрозу. В
этом случае просьба не жаловаться, если данные на
подчиненном сервере не будут соответствовать
данным на головном сервере, - вас предупреждали.
Пример: slave-skip-errors=1062,1053 или
slave-skip-errors=all
|
skip-slave-start |
Указывает компьютеру, на котором установлен
подчиненный сервер, что при его запуске не должен
запускаться подчиненный сервер. Пользователь может
запустить его позже при помощи команды SLAVE START .
|
slave_compressed_protocol=# | Если 1, то использовать сжание в клиент/серверном протоколе связи, если оба, и сервер и клиент, поддерживают сжатие. |
slave_net_timeout=# | Время ожидания (в секундах) дополнительных данных от головного сервера, после чего чтение будет прервано. |
4.10.6 SQL-команды, относящиеся к репликации
Управление репликацией производится командами SQL. Ниже приводится краткое описание команд:
Команда | Описание |
SLAVE START | Запускает поток подчиненного сервера (подчиненный сервер) |
SLAVE STOP | Завершает поток подчиненного сервера. Также как и SLAVE START , этот оператор можно использовать с опциями
IO_THREAD и SQL_THREAD . (подчиненный сервер)
|
SET SQL_LOG_BIN=0 | Блокирует ведение записей в журналах
обновлений, если пользователь имеет привилегию SUPER . В противном случае ничего
не выполняет (головной сервер)
|
SET SQL_LOG_BIN=1 | Отменяет блокировку ведения записей в
журналах обновлений, если пользователь имеет привилегию SUPER . В противном
случае ничего не выполняет (головной сервер)
|
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=n | Пропускает последующие n событий на головном сервере. Опция допустима, если поток подчиненного сервера не запущен, в противном случае будет выдана ошибка. Полезна для восстановления после сбоев репликации. |
RESET MASTER | Удаляет все двоичные журналы, перечисленные в
индексном файле, и делает индексный файл двоичных журналов пустым. Для версий
ниже 3.23.26 используйте команду FLUSH SLAVE (головной сервер)
|
RESET SLAVE | Заставляет подчиненный сервер "забыть" свою
точку положения репликации в журналах головного сервера. Для версий ниже
3.23.26 эта команда называется FLUSH SLAVE (подчиненный сервер)
|
LOAD TABLE tblname FROM MASTER | Загружает копию таблицы из
головного на подчиненный сервер. Используется главным образом для отладки
команды LOAD DATA FROM MASTER , но некоторые "пользователи-гурманы" могут найти
ей и другие применения. Если вы относите себя к числу обычных, не отягощенных
хакерскими амбициями пользователей, данную опцию применять не стоит.
Требуется, чтобы у пользователя репликации, использущегося в соединении с головным
сервером, присутствовали привилегии RELOAD и SUPER на головном сервере.
(подчиненный сервер).
|
LOAD DATA FROM MASTER | Присутствует в версиях выше 4.0.0.
Создает образ головного сервера и копирует его на подчиненный сервер.
Требуется, чтобы у пользователя репликации, использущегося в соединении с головным
сервером, присутствовали привилегии RELOAD и SUPER на головном сервере.
Обновляет
значения MASTER_LOG_FILE и MASTER_LOG_POS таким образом, чтобы подчиненный
сервер начинал репликацию из конкретной позиции. Будет обрабатывать ограничения
таблиц и баз данных, указанные в опциях replicate-* . При этом, пока происходит
создание образа, могут использоваться лишь таблицы MyISAM и требуется
глобальная блокировка чтения на головном сервере. В будущем планируется
обеспечить работу этой команды с таблицами InnoDB и устранить необходимость
глобальной блокировки чтения при помощи интерактивного резервного копирования,
не требующего блокировки.
Заметьте, LOAD DATA FROM MASTER НЕ копирует ни одну таблицу в
базе данных mysql. Это сделано для того, чтобы было легко управлять разными
пользователями на головном и подчиненном серверах.
|
CHANGE MASTER TO master_def_list |
Заменяет параметры головного сервера значениями, заданными в списке
master_def_list , и перезапускает поток подчиненного сервера. master_def_list -
это список с разделителем-запятой, содержащий значения master_def , где
master_def - одно из следующих значений: MASTER_HOST, MASTER_USER,
MASTER_PASSWORD, MASTER_PORT, MASTER_CONNECT_RETRY, MASTER_LOG_FILE,
MASTER_LOG_POS . Например:
CHANGE MASTER TO MASTER_HOST='master2.mycompany.com', MASTER_USER='replication', MASTER_PASSWORD='bigs3cret', MASTER_PORT=3306, MASTER_LOG_FILE='master2-bin.001', MASTER_LOG_POS=4;Следует указывать только те значения, которые подлежат изменению. Не указанные значения останутся неизменными, за исключением тех случаев, когда изменяется хост или порт. В этом случае подчиненный сервер считает, что поскольку изменяется хост или порт, головной сервер становится другим. Следовательно, старые значения и точки положения в журнале будут автоматически заменены на значение пустой строки и 0 соответственно (начальные значения). Обратите
внимание: если подчиненный сервер перезапускается, он сохраняет "память" о
своем последнем головном сервере. Если это нежелательно, можно перед
перезапуском удалить файл `master.info' - тогда подчиненный сервер будет
считывать информацию о своем головном сервере из файла `my.cnf' или из командной
строки. Эта команда используется для настройки подчиненного сервера при наличии
образа головного сервера, а также записей из журнала и сдвига головного
сервера, которые соответствуют образу. Можно выполнить команду
CHANGE MASTER TO MASTER_LOG_FILE='log_name_on_master', MASTER_LOG_POS=log_offset_on_masterна подчиненном сервере после восстановления образа (подчиненный сервер) |
SHOW MASTER STATUS | Выводит информацию о состоянии головного сервера, исходя из информации в двоичных журналах (головной сервер) |
SHOW SLAVE HOSTS | Присутствует в версии 4.0.0 и выше. Выводит список подчиненных серверов, связанных в текущее время с головным сервером (подчиненный сервер) |
SHOW SLAVE STATUS | Выводит информацию о состоянии существенных параметров потока подчиненного сервера (головной сервер) |
SHOW MASTER LOGS | Присутствует только начиная с версии
3.23.28. Выводит список двоичных журналов головного сервера. Эту команду
следует использовать перед вызовом команды PURGE MASTER LOGS TO для определения
того, какие из журналов можно удалить (головной сервер)
|
SHOW BINLOG EVENTS [ IN 'logname' ] [ FROM pos ] [LIMIT [offset,] rows ]
@tab Показывает события в двоичном журнале обновлений. Преимущественно
применяется для тестирования/отладки, но может также использоваться и для
обычных клиентов, по какой-либо причине нуждающихся в чтении содержимого
двоичных журналов (головной сервер).
| |
SHOW NEW MASTER FOR SLAVE
WITH
MASTER_LOG_FILE='logfile'
AND MASTER_LOG_POS=pos AND
MASTER_LOG_SEQ=log_seq AND
MASTER_SERVER_ID=server_id |
Эта команда используется, когда подчиненному
серверу, связанному с головным сервером,
который, возможно, является "мертвым" или
недоступным, нужно отключить репликации на
другом подчиненном сервере, связанном с тем же головным сервером. Команда
возвратит пересчитанные координаты репликации (имя файла журнала и позицию в
нем), и вывод этой команды может использоваться в последующей команде
CHANGE MASTER TO . Обычным пользователям данная команда, как правило,
никогда не понадобится: она главным образом служит для внутреннего
использования в отказобезопасном репликационном коде. В будущем возможны
изменения синтаксиса опции, если будет найден более интуитивно понятный способ
описания этой операции.
|
PURGE MASTER LOGS TO 'logname' |
Присутствует начиная с версии 3.23.28.
Удаляет все журналы репликации, которые
перечислены в индексном файле журналов до
передаваемого журнала, и удаляет их из
индексного файла журналов. Таким образом
передаваемый журнал становится первым в
индексном файле журналов. Пример:
PURGE MASTER LOGS TO 'mysql-bin.010'Эта команда не выполнит никаких действий и возвратит ошибку, если имеется активный подчиненный сервер, который в текущее время читает данные из одного из журналов, который должен быть удален. Однако если имеется бездействующий подчиненный сервер и происходит удаление одного из журналов, который он хочет прочитать, то после того, как подчиненный сервер "поднимется", он станет неспособным к репликации. Команда может быть безопасно выполнена на подчиненных серверах во время процесса репликации - не нужно останавливать процесс. Сначала необходимо проверить все подчиненные серверы при помощи команды SHOW SLAVE STATUS , чтобы
увидеть, какой журнал используется, затем
вывести список журналов головного сервера при
помощи команды SHOW MASTER LOGS , найти самый
ранний журнал среди всех подчиненных серверов
(если все подчиненные серверы получили
последние обновления, это будет последний
журнал в списке), сделать резервные копии
всех журналов, которые должны быть удалены
(необязательно), и очистить все до целевого
журнала.
|
4.10.7 Часто задаваемые вопросы по репликации
Вопрос: Как сконфигурировать подчиненный сервер, если головной сервер уже запущен, и я не хочу его останавливать?
Ответ: Есть несколько возможностей. Если имеется резервная копия головного
сервера в некоторой точке, имя двоичного журнала и сдвиг (от вывода SHOW
MASTER STATUS
), соответствующий образу, выполните следующие действия:
- Удостоверьтесь, что подчиненному серверу назначен уникальный идентификатор.
-
Выполните команды
CHANGE MASTER TO MASTER_HOST='master-host-name', MASTER_USER='master-user-name', MASTER_PASSWORD='master-pass', MASTER_LOG_FILE='recorded-log-name', MASTER_LOG_POS=recorded_log_pos
-
Выполните команду
SLAVE START
Если нет резервной копии головного сервера, существует быстрый способ создать ее в той же последовательности действий:
-
gtar zcf /tmp/backup.tar.gz /var/lib/mysql
(или разновидность данной команды) -
SHOW MASTER STATUS
- удостоверьтесь в том что вывод этой команды сохранен - он пригодится позже -
UNLOCK TABLES
FLUSH TABLES WITH READ LOCK
После этого следуйте инструкциям для случая, когда имеется образ, имя двоичного журнала и сдвиг. Можно использовать один и тот же образ для конфигурации нескольких подчиненных серверов. Пока существуют двоичные журналы головного сервера, установить подчиненный сервер можно через несколько дней, а то и через месяц - при наличии образа головного сервера. Теоретически промежуток ожидания может быть бесконечным. На практике существуют два ограничения - дисковое пространство головного сервера, которое будет занято старыми журналами, и время, которое потребуется подчиненному серверу, чтобы догнать головной сервер.
В версии 4.0.0 и выше можно также использовать команду LOAD DATA FROM
MASTER
. Это удобная команда, которая создает образ, восстанавливает его на
подчиненном сервере и сразу же корректирует имя журнала и сдвиг на
подчиненном сервере. Именно команду LOAD DATA FROM MASTER
можно
рекомендовать как способ установки подчиненного сервера. Имейте в виду,
однако, что при использовании данной команды чтение может быть блокировано
на долгое время. В настоящее время эта команда еще не реализована
настолько эффективно, как бы нам хотелось. Если имеются большие таблицы,
пока лучше использовать локальный архив tar после выполнения команды FLUSH
TABLES WITH READ LOCK
.
В
: Должен ли подчиненный сервер постоянно быть подсоединен к головному
серверу?
О
: Нет, не должен. Можно прекращать работу подчиненного сервера или
оставлять его отсоединенным на несколько часов или даже дней, затем
повторно подгонять подчиненный сервер к произошедшим обновлениям, и
затем снова отсоединять или останавливать его на некоторое время.
Таким образом можно, например, использовать установку
"головной-подчиненный" через коммутационную связь, работающую в
течение коротких периодов времени. При такой реализации, однако,
нельзя гарантировать, что в какое-либо заданное время подчиненный
сервер будет синхронизирован с головным сервером, если вы для этого не
примете специальных мер. В будущем будет добавлена опция для
блокировки головного сервера до тех пор, пока хотя бы один подчиненный
сервер находится в синхронизации с ним.
В
: Как заставить головной сервер блокировать обновления, пока
происходит соединение с подчиненным сервером?
О
: Выполните следующие команды:
-
Головной сервер:
FLUSH TABLES WITH READ LOCK
-
Головной сервер:
SHOW MASTER STATUS
- запомните имя журнала и сдвиг -
Подчиненный сервер:
SELECT MASTER_POS_WAIT('recorded_log_name', recorded_log_offset
) После выполнения этой команды подчиненный сервер будет синхронизирован с головным сервером -
Головной сервер:
UNLOCK TABLES
- теперь головной сервер может продолжить обновления.
В
: Почему иногда после перезапуска подчиненного сервера я вижу более
одного потока Binlog_Dump
на головном сервере?
О:
Поток Binlog_Dump
является непрерывным процессом, который
обрабатывается сервером следующим способом:
- Осуществляется захват обновлений.
-
Если не остается больше обновлений, входит в число
pthread_cond_wait()
, откуда его можно "пробудить", выполнив следующее обновление, или уничтожить. -
После пробуждения проверяется причина пробуждения. Если нет причины
прекращения цикла, цикл
Binlog_dump
продолжается. - При возникновении какой-либо фатальной ошибки, такой как обнаружение "мертвого" клиента, цикл прекращается.
Таким образом, если поток подчиненного сервера прекратится на подчиненном
сервере, соответствующий поток Binlog_Dump
на головном сервере не будет
замечать этого, пока не произойдет по крайней мере одного обновления на
головном сервере (или уничтожения потока), которое необходимо, чтобы
пробудить его из числа pthread_cond_wait()
. Тем временем подчиненный
сервер может открыть другое соединение, результатом которого будет другой
поток Binlog_Dump
.
Эта проблема не должна присутствовать в версии 3.23.26 и более поздних
версиях. В версии 3.23.26 для каждого репликационного сервера добавляется
идентификатор server-id
, и теперь все старые процессы-зомби на головном
сервере уничтожаются при присоединении нового репликационного потока из
того же самого подчиненного сервера.
В
: Как прокручивать журналы репликации?
О
: В версии 3.23.28 нужно использовать команду PURGE MASTER LOGS TO
после
определения тех журналов, которые должны быть удалены, и выборочно сделать
резервные копии этих журналов. В более ранних версиях этот процесс намного
более трудоемкий, и не может быть безопасно выполнен без остановки всех
подчиненных серверов, если планируется повторное использование имен
журналов. Нужно будет остановить потоки подчиненного сервера,
отредактировать индексный файл двоичного журнала, удалить все старые
журналы, перезапустить головной сервер, запустить потоки подчиненного
сервера и затем удалить файлы старых журналов.
В
: Как сделать апгрейд сервера во время репликации?
О
: Если модернизируемая версия ниже 3.23.26, нужно лишь блокировать
таблицы головного сервера, позволить подчиненному серверу подогнать
обновления, затем выполнить команду FLUSH MASTER
на головном сервере и
команду FLUSH SLAVE
на подчиненном сервере, чтобы очистить журналы,
затем перезапустить новые версии на головном и подчиненном серверах.
Обратите внимание: подчиненный сервер может останавливаться на
некоторое время - пока головной сервер записывает в журнал все
обновления, подчиненный сервер будет способен подогнать обновления как
только сможет начать работу и подсоединиться к головному серверу.
В версиях выше 3.23.26 осуществляется блокировка протокола репликации для обновлений. Таким образом можно делать апгрейд до более свежей версии 3.23 головного и подчиненного серверов динамически. Помимо этого, на головном и подчиненном серверах могут быть запущены различающиеся версии MySQL, если обе версии выше 3.23.26.
Q
: Какие проблемы могут возникать при установке двухсторонней
репликации?
A
: В настоящее время для репликаций MySQL не поддерживается никакого
протокола блокировки между головным и подчиненным сервером, который
обеспечивал бы неделимость распределенных (междусерверных) обновлений.
Другими словами, клиент A может делать обновления на головном сервере
1, и в это же время, перед тем, как эти обновления скопируются на
головной сервер 2, клиент B может делать обновления на головном
сервере 2, из-за которых обновления клиента A будут выполняться не
так, как на головном сервере 1 компании. Таким образом, когда
обновления, сделанные клиентом A, будут перенесены на головной сервер
2, таблицы, полученные в результате, будут отличаться от таблиц на
головном сервере 1. В этом случае таблицы на двух серверах будут
разными, даже если обновления, произошедшие на головном сервере 2,
также будут скопированы на головной сервер 1. Отсюда следует, что не
стоит соединять в цепочку два сервера двусторонней репликационной
связью, если вы не уверены, что обновления будут безопасно выполняться
в любом порядке, или если вы не обрабатываете каким-либо образом такие
неупорядоченные обновления где-либо в клиентском коде.
Важно понять также и то, что если двухсторонний механизм репликации и повышает производительность, то не настолько, что это могло бы отразиться на обновлениях. Каждый из серверов должен выполнять такое же количество обновлений, как и один сервер, разве что уменьшатся конфликты при блокировках, потому что обновления, происходящие на другом сервере, будут сериализованы в одном потоке подчиненного сервера. Эта выгода, тем не менее, может быть компенсирована задержками в сети.
Q
: Как использовать репликацию для повышения производительности
системы?
A
: Установите один сервер как головной и направляйте все записи к
нему, а также сконфигурируйте такое количество подчиненных серверов,
на какое у вас хватит средств и дискового пространства, и распределите
чтение между головным сервером и подчиненными серверами. Можно также
запустить подчиненные серверы с опциями --skip-bdb
,
--low-priority-updates
и --delay-key-write=ALL
, чтобы
получить увеличение скорости на подчиненном сервере. В данном случае
подчиненный сервер для повышения скорости будет использовать
нетранзакционные таблицы MyISAM
вместо таблиц BDB
.
Q
: Что нужно сделать, чтобы подготовить свой клиентский код для
использования репликации, повышающей производительность?
A
: Если та часть вашего кода, которая отвечает за доступ к базе
данных, является достаточно абстрактной и модульной, преобразование ее
для работы с установленной репликацией произойдет очень гладко и
просто - для этого нужно лишь изменить реализацию доступа для чтения к
базе данных от некоторого подчиненного сервера или головного сервера
так, чтобы запись всегда производилась на головной сервер. Если же ваш
код не имеет такого уровня абстракции, то установка системы репликации
окажется для вас хорошей и мотивированной возможностью почистить свой
код. Начните с создания библиотеки или оболочки со следующими
функциями:
Safe_writer_connect()
Safe_reader_connect()
Safe_reader_query()
Safe_writer_query()
Префикс safe_
означает, что функция будет нести ответственность за
обработку всех возникающих ошибок.
После этого нужно преобразовать клиентский код так, чтобы он использовал
библиотеку оболочки. Вначале все это покажется лишней головной болью, но
в конечном счете ваши усилия окупятся. Все приложения, построенные в
соответствии с приведенной выше схемой, смогут "приобщиться" к
преимуществам решения один головной/много подчиненных. Код будет гораздо
легче поддерживать, а добавление опций поиска неисправностей станет
тривиальным. К примеру, если вам захочется узнать, какой запрос среди
многих тысяч возвращает ошибку или реализовать регистрацию
продолжительности выполнения каждого запроса, то понадобится изменить
всего пару функций. Если у вас уже написано много кода, то для
автоматизации задачи его преобразования можно использовать написанную
Монти утилиту replace
, которая имеется в стандартном дистрибутиве MySQL,
или написать собственный сценарий на Perl. Остается надеяться, что ваш код
удовлетворяет некоторой распознаваемой схеме. В противном случае будет
лучше переписать его каким-либо образом, или, по крайней мере, вручную
подогнать его под схему.
Обратите внимание: имена функций, конечно же, можно использовать любые. Важно иметь унифицированный интерфейс для подключения для чтения, подсоединения для записи, выполнения чтения и выполнения записи.
Q
: В каких случаях репликация MySQL может улучшить производительность
системы, и насколько?
A
: Механизм репликации MySQL наиболее эффективен для системы, где чтение
производится часто, а запись - редко. Теоретически, используя установку
один головной/много подчиненных, можно наращивать ее, добавляя подчиненные
серверы, пока не исчерпается пропускная способность сети или количество
обновлений не вырастет настолько, что головной сервер не сможет
обрабатывать их.
Чтобы определить какое количество подчиненных серверов можно установить,
прежде чем выгоды от дополнительных ресурсов не перестанут оправдывать
затраты, и насколько увеличится производительность вашего сайта, нужно
знать структуру запросов и опытным путем (тестированием) определить связь
между производительностью чтения (количество считываний за секунду, или
max_reads
) и записи (max_writes
) на типовом головном сервере и типовом
подчиненном сервере. В приведенном примере показан достаточно упрощенный
подсчет того, что можно получить, используя механизм репликации для
предполагаемой системы.
Предположим, что загрузка системы состоит из 10% операций записи и 90%
операций чтения, и известно что max_reads = 1200 - 2 * max_writes
, или
другими словами, наша система, не делая записей, может делать 1200
операций чтения за секунду, средняя скорость записи вдвое ниже, чем
средняя скорость чтения, а зависимость между этими величинами линейная.
Предположим, что головной сервер и подчиненный сервер имеют одинаковую
мощность, и имеется N подчиненных серверов и 1 головной. Тогда для каждого
сервера (головного или подчиненного) имеем:
reads = 1200 - 2 * writes
(по результатам тестирования)
reads = 9 * writes / (N + 1)
(операции чтения распределяются по серверам,
но запись выполняются на всех серверах)
9 * writes/(N+1) + 2 * writes = 1200
writes = 1200/(2 + 9/(N+1)
Таким образом, если N = 0, что означает отсутствие репликации, система может обрабатывать 1200/11, т.е. около 109 записей в секунду (а число операций чтения, в соответствии с нашими допущениями для данной системы, будет в 9 раз больше, чем число операций записи).
Если N = 1, можно получить 184 операций записи в секунду.
Если N = 8, можно получить до 400 операций записи в секунду.
Если N = 17, то - 480 операций записи в секунду.
В конечном счете, если N приближается к бесконечности (а бюджет к минус бесконечности), можно получить около 600 записей в секунду, при этом производительность системы увеличится приблизительно в 5,5 раз. Однако при использовании лишь 8 серверов производительность уже увеличивается почти в 4 раза.
Обратите внимание: в приведенных вычислениях мы принимали, что сеть имеет неограниченную пропускную способность, и пренебрегали некоторыми другими факторами, которые могут оказаться существенными для системы. Во многих случаях такие подсчеты могут и не дать точного прогноза того, как отразится на системе добавление N подчиненных серверов. Однако определить, улучшат ли репликации производительность вашей системы, а если да, то насколько, вам помогут ответы на следующие вопросы:
- Каково отношение числа операций чтения к числу операций записи в вашей системе?
- Насколько увеличится количество записей, которые сможет обрабатывать один сервер, при уменьшении количества операций чтения?
- Сколько подчиненных серверов можно установить при текущей пропускной способности сети?
Q
: Как использовать репликацию для обеспечения избыточности и хорошей
доступности?
A
: С учетом сегодняшних возможностей репликации нужно будет установить
головной сервер и подчиненный сервер (или несколько подчиненных
серверов), и написать сценарий для мониторинга головного сервера - для
определения, включен ли он, и уведомления приложения и подчиненных
серверов об изменениях головного сервера в случае ошибки. Ниже
приведено несколько советов:
-
Для уведомления подчиненного сервера об изменениях головного сервера
используйте команду
CHANGE MASTER TO
. -
Хороший способ информирования приложений о местоположении головного
сервера - иметь на головном сервере динамической компонент DNS. При
использовании
bind
для динамического обновления DNS можно применятьnsupdate
. -
Запустите подчиненные серверы с опцией
log-bin
, но безlog-slave-updates
. Таким образом подчиненный сервер будет готов стать головным сервером после выполнения командSTOP SLAVE; RESET MASTER
иCHANGE MASTER TO
на других подчиненных серверах. Указание этой опции обеспечит также возможность перехвата ложных обновлений, которые могут происходить из-за ошибочной конфигурации подчиненного сервера (в идеале можно настроить права доступа таким образом, чтобы никакой клиент не мог производить обновления на подчиненном сервере иначе, чем через поток подчиненного сервера) в сочетании с ошибками в клиентских программах (они никогда не должны производить обновления на подчиненном сервере непосредственно).
В настоящее время мы работаем над интеграцией системы автоматического выбора головного сервера в MySQL, но пока эта функция не будет готова, придется создавать собственные средства контроля.
Q: Каким образом подчиненный сервер сохраняет информацию о том, где он находится на головном сервер?
A: Подчиненный сервер использует файл в каталоге данных, определенный
в опции master-info-file=filename
. В этом файле находится вся информация,
необходимая подчиненному сервер для запроса новых обновлений. Этот файл содержит следующую информацию:
Номер строки | Описание |
1 | Имя файла двоичного журнала |
2 | Позиция в файле журнала |
3 | Удаленный компьютер (головной сервер) |
4 | Пользователь |
5 | Пароль |
6 | Порт |
7 | Интервал в секундах между соединениями |
4.10.8 Поиск неисправностей репликации
Если вы следовали инструкциям, но установленный механизм репликации не работает, прежде всего следует искать пользовательские ошибки. Выполните следующие проверки:
-
Производит ли головной сервер записи в двоичный журнал? Проверьте это
при помощи команды
SHOW MASTER STATUS
. Если да, значениеPosition
будет отличным от нуля. Если нет, проверьте, запущен ли головной сервер с опциейlog-bin
и установлен лиserver-id
. -
Запущен ли подчиненный сервер? Проверьте это при помощи команды
SHOW SLAVE STATUS
. Ответ находится в столбцеSlave_running
. Если нет, проверьте опции подчиненного сервера и просмотрите сообщения в журнале ошибок. -
Если подчиненный сервер запущен, установил ли он соединение с головным
сервером? Выполните команду
SHOW PROCESSLIST
, найдите поток, которому соответствует значениеsystem user
в столбцеUser
иnone
в столбцеHost
, и проверьте столбецState
. Если в нем находится значениеconnecting to master
, проверьте привилегии для пользователя репликации на головном сервере, имя хоста головного сервера, установку DNS, посмотрите, запущен ли головной сервер в текущее время, доступен ли он для подчиненного сервера. После этого, если все окажется в порядке, просмотрите журналы ошибок. -
Если подчиненный сервер был запущен, но затем остановился, посмотрите
на вывод команды
SHOW SLAVE STATUS
и проверьте журналы ошибок. Такое обычно случается, когда некоторый запрос, успешно выполняющийся на головном сервере, не выполняется на подчиненном. Если создан корректный образ головного сервера и данные на подчиненном сервере обновлялись только через поток подчиненного сервера, этого происходить не должно. Но если все же такое случилось - значит, имеет место ошибка; как сообщить о ней, читайте ниже. -
Если запрос, успешно выполняемый на головном сервере, не выполняется
на подчиненном, и нельзя выполнить полную ресинхронизацию базы данных
(ее стоит выполнить), попробуйте сделать следующее:
-
Сначала проверьте: возможно где-либо случайно оказалась ненужная
запись. Разберитесь, как она оказалась там, затем удалите ее, и
выполните команду
SLAVE START
. - Если вы проделали все, о чем написано выше, и ничего не помогло или этого сделать нельзя, попытайтесь понять, будет ли безопасно выполнить обновления вручную (если необходимо) и после этого игнорировать следующий запрос от головного сервера.
-
Если вы решили пропустить следующий запрос, выполните команды
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; SLAVE START;
чтобы пропустить запрос, не использующий функцииAUTO_INCREMENT
илиLAST_INSERT_ID()
. В противном случае выполните командыSET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; SLAVE START
. Причина того, что запросы, использующие функцииAUTO_INCREMENT
илиLAST_INSERT_ID()
, обрабатываются по-другому, заключается в том, что они создают два события в двоичном журнале головного сервера. - Если вы уверены, что подчиненный сервер был успешно запущен и синхронизирован с головным сервером, а также что обновления таблиц не производились вне потока подчиненного сервера, пришлите нам отчет об ошибке, и вам не потребуется опять повторять описанные выше уловки.
-
Сначала проверьте: возможно где-либо случайно оказалась ненужная
запись. Разберитесь, как она оказалась там, затем удалите ее, и
выполните команду
- Удостоверьтесь, что вы не внесли старой ошибки при апгрейде MySQL до более новой версии.
-
Если ничего не помогает, просмотрите журналы ошибок. Если журналы
большие, выполните команду
grep -i slave /path/to/your-log.err
на подчиненном сервере. Искать ошибку на головном сервере - не лучшая идея, поскольку в его журналах находятся лишь системные ошибки общего характера; если это возможно, он посылает ошибку на подчиненный сервер, когда что-либо происходит не так, как надо.
Если вы убедились, что пользовательская ошибка здесь ни при чем, однако механизм репликации по-прежнему не работает или работает нестабильно, пришло время начать работу над отчетом об ошибке. Вы должны предоставить нам столько информации, сколько нужно, чтобы отследить ошибку. Пожалуйста, уделите отчету об ошибке нужное количество времени и усилий, чтобы сделать его хорошо. В идеале мы хотели бы иметь контрольный пример в формате, который находится в каталоге `mysql-test/t/rpl*' исходного дерева. Отослав такой контрольный пример, в большинстве случаев можно рассчитывать на получение патча в течение одного-двух дней, хотя, конечно, это время может варьироваться в зависимости от множества факторов.
Еще один хороший способ проинформировать нас об ошибке - написать простую программу с легко конфигурируемыми параметрами соединения для головного и подчиненного серверов, в которой будет продемонстрирована проблема наших систем. Программа может быть написана на Perl или на C, в зависимости от того, какой язык вы знаете лучше.
Подготовив информацию об ошибке одним из двух способов, используйте
утилиту mysqlbug
, чтобы создать отчет об ошибке, и пошлите его по адресу
bugs@lists.mysql.com. Если же вы имеете дело с фантомом - проблемой,
которая имеет место, но вы по какой-либо причине не можете ее
воспроизвести по желанию:
- Убедитесь, что эта проблема не вызвана пользовательской ошибкой. Например, при обновлении подчиненного сервера вне потока подчиненного сервера данные будут не синхронизированы, и могут быть нарушения уникальных ключей при обновлениях. В этом случае поток подчиненного сервера остановится и будет ждать, пока таблицы не будут очищены вручную, для приведения их в синхронизированный режим.
-
Запустите подчиненный сервер с опциями
log-slave-updates
иlog-bin
- при этом в журнал будет заноситься информация обо всех обновлениях, происходящих на подчиненном сервере. -
Сохраните все доказательства наличия ошибки перед сбросом репликации.
Если у нас нет информации о проблеме, или имеется только отрывочная
информация, потребуется время, чтобы найти источник проблемы. Вы
должны собрать следующие "свидетельства":
- Все двоичные журналы головного сервера
- Весь двоичный журнал подчиненного сервера
- Вывод команды
SHOW MASTER STATUS
на головном сервере во время обнаружения проблемы - Вывод команды
SHOW SLAVE STATUS
на головном сервере во время обнаружения проблемы - Журналы ошибок головного сервера и подчиненного сервера
-
Для изучения двоичных журналов используйте утилиту
mysqlbinlog
. Таким образом можно находить проблемные запросы, например:mysqlbinlog -j pos_from_slave_status /path/to/log_from_slave_status | head
Собрав "свидетельства" о проблеме-фантоме, попробуйте сначала организовать их в отдельный контрольный пример. После этого сообщите о проблеме по адресу bugs@lists.mysql.com, описав эту проблему во всех подробностях.
Go to the first, previous, next, last section, table of contents.