Автор: Алексей Паутов
Источник: RussianLDP:MySQL
Всего: 450 страниц в формате А4.
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
. Подробности об этом вызове в разделе
"4.5.2 Синтаксис ANALYZE
TABLE
".
Вы можете оптимизировать и другие типы таблиц запуском mysqld
с опциями --skip-new
или --safe-mode
, но в этом
случае OPTIMIZE TABLE
превратится в вызов ALTER
TABLE
.
OPTIMIZE TABLE
работает следующим образом:
OPTIMIZE TABLE
для таблиц типа MyISAM
эквивалентен вызову myisamchk --quick --check-changed-tables
--sort-index --analyze
.
Обратите внимание, что таблица будет блокирована в течение всего времени
работы команды OPTIMIZE TABLE
!
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
. Подробности в разделе "
4.5.5.1 Получение информации о базах данных, таблицах, столбцах и индексах
".
Если таблица не изменилась после последней команды ANALYZE
TABLE
, она не будет проанализирована снова.
FLUSH
FLUSH flush_option [,flush_option]
Вы должны использовать команду FLUSH
, если Вы хотите очищать
внутренние кэши MySQL. Для выполнения FLUSH
Вы должны иметь
право RELOAD.
flush_option
может быть любой из следующего списка:
HOSTS | Освобождает ведущие таблицы кэша. Вы
должны это сделать, если некоторые из Ваших хостов изменяют IP, или если Вы
получили сообщение об ошибке "Host ... is blocked ". Когда в
строке для данного компьютера происходит больше, чем
max_connect_errors ошибок за время связи с сервером, MySQL
приходит к выводу, что что-то пошло неправильно, и блокирует компьютер.
Подробности в разделе "8.2.4 Ошибка
Host '...' is blocked . Вы можете запустить
mysqld с опцией -O max_connection_errors=999999999 ,
чтобы избежать этого сообщения об ошибке. |
LOGS | Закрывает и вновь открывает все журналы.
Если Вы определили журнал модификаций или двоичный журнал без расширения,
номер расширения журнала будет увеличен на один относительно предыдущего
файла. Если Вы использовали расширение в имени файла, MySQL закроет и вновь
откроет журнал модификаций. Подробности в разделе
"4.9.3 Файл регистрации модификаций".
Это эквивалентно посылке на сервер mysqld сигнала
SIGHUP . |
PRIVILEGES | Перезагружает привилегии из таблиц в
базе данных mysql . |
TABLES | Закрывает все открытые таблицы. |
[TABLE|TABLES] table_name [,table_name...] |
Применяет предыдущую команду только к заданным таблицам. |
TABLES WITH READ LOCK | Закрывает все открытые
таблицы и блокирует все таблицы для всех баз данных с доступом только на
чтение, пока не будет выполнена команда UNLOCK TABLES . Это очень
удобный способ получить резервную копию, если Вы имеете файловую систему,
подобную Veritas. |
STATUS | Сбрасывает большинство переменных состояния к нулю. Используется при отладке запроса. |
Вы можете также обращаться к каждой из команд, показанных выше с помощью
утилиты mysqladmin
, используя команды flush-hosts
,
flush-logs
, reload
или flush-tables
.
KILL
KILL thread_id
Каждое подключение к mysqld
выполняется в отдельном процессе.
Вы можете видеть запущенные процессы командой SHOW PROCESSLIST
и уничтожать процесс командой KILL thread_id
.
Если Вы имеете привилегию process, Вы можете видеть и уничтожать все процессы. Иначе Вы можете видеть и уничтожать только Ваши собственные процессы.
Вы можете также использовать команды mysqladmin processlist
и
mysqladmin kill
, чтобы исследовать и уничтожать процессы.
При вызове KILL
для процесса устанавливается флаг kill
flag
.
В большинстве случаев может требоваться некоторое время для того, чтобы
процесс уничтожился, поскольку флаг kill flag
может быть
проверен только в специфических интервалах:
SELECT
, ORDER BY
и GROUP
BY
флажок будет проверен после чтения блока строк. Если он установлен,
инструкция будет прервана.
ALTER TABLE
флаг будет проверен прежде, чем
каждый блок строк считается из первоначальной таблицы. Если он установлен,
команда будет прервана, а временная таблица удалена.
UPDATE TABLE
и DELETE TABLE
,
флажок будет проверен после каждого чтения блока и после каждого обновления
или удаления строки. Если он установлен, инструкция будет прервана. Обратите
внимание, что, если Вы не используете транзакции, сделанные в таблице
изменения не будут отменены!
GET_LOCK()
прервется с NULL
.
INSERT DELAYED
быстренько сбросят на диск все
строки, которые у них лежат в памяти и завершатся.
Locked
), блокировка таблицы будет быстро прервана.
write
, запись немедленно прерывается с сообщением об
ошибке переполнения диска.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
обеспечивает информацию относительно баз данных, таблиц,
столбцов или информацию состояния сервера. Если используется часть
LIKE wild
, строка wild
может быть строкой, которая
использует групповые символы SQL `%' и `_'.
Вы можете использовать db_name.tbl_name
как вариант для
tbl_name FROM db_name
. Эти две инструкции эквивалентны:
mysql> SHOW INDEX FROM mytable FROM mydb; mysql> SHOW INDEX FROM mydb.mytable;
SHOW DATABASES
вносит в список базы данных на сервере
MySQL. Вы можете также получать этот список, используя команду
mysqlshow
.
SHOW TABLES
вносит в список таблицы в заданной базе данных.
Вы можете также получать этот список, используя команду
mysqlshow db_name
.
ОБРАТИТЕ ВНИМАНИЕ: Если пользователь не имеет привилегий
для таблицы, соответствующая таблица не будет обнаруживаться в выводе
SHOW TABLES
или mysqlshow db_name
.
SHOW OPEN TABLES
вносит в список таблицы, которые являются в
настоящее время открытыми в кэше таблиц.
Подробнее см. раздел "5.4.6 Как MySQL
открывает и закрывает таблицы". Поле Comment
сообщает
сколько раз таблица кэшируется (cached
) и используется
(in_use
).
SHOW COLUMNS
вносит в список столбцы в данной таблице. Если
Вы определяете опцию FULL
, Вы также получите привилегии, которые
Вы имеете для каждого столбца. Если типы столбцов отличны от ожидаемых, они
будут основаны на инструкции CREATE TABLE
, заметьте, что MySQL
иногда сам изменяет типы столбца.
Инструкция DESCRIBE
обеспечивает информацию, подобную
SHOW COLUMNS
.
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 (не с 0!). |
Column_name | Имя столбца. |
Collation | Как столбец сортируется в индексе. В
MySQL это может иметь варианты `A' (по возрастанию) или
NULL (не сортируемый). |
Cardinality | Число уникальных значений в индексе.
Это модифицируется запуском isamchk -a . |
Sub_part | Число индексированных символов, если
столбец только частично индексирован. NULL если весь ключ
индексирован в полном объеме. |
Comment | Различные замечания. Пока это сообщает, является ли индекс полнотекстовым (FULLTEXT) или нет. |
Обратите внимание, что, поскольку Cardinality
будет
рассчитано, основываясь на статистике, сохраненной как целые числа, оно не
обязательно точно для маленьких таблиц.
SHOW TABLE STATUS
SHOW TABLE STATUS [FROM db_name] [LIKE wild]
SHOW TABLE STATUS
(новинка в Version 3.23) работает подобно
SHOW STATUS
, но обеспечивает много информации относительно
каждой таблицы. Вы можете также получать этот список, используя команду
mysqlshow --status db_name
. Следующие столбцы возвращены:
Столбец | Зачем он нужен |
Name | Имя таблицы. |
Type | Тип таблицы. Подробности в разделе "7 Типы таблиц MySQL". |
Row_format | Формат хранения строки (фиксированный, динамический или сжатый). |
Rows | Число строк. |
Avg_row_length | Средняя длина строки. |
Data_length | Длина файла данных. |
Max_data_length | Максимальная длина файла данных. |
Index_length | Длина индексного файла. |
Data_free | Число распределенных, но не используемых байт. |
Auto_increment | Следующее значение auto_increment. |
Create_time | Когда таблица была создана. |
Update_time | Когда файл данных был в последний раз модифицирован. |
Check_time | Когда таблица была в последний раз проверена на ошибки. |
Create_options | Дополнительные параметры,
используемые с CREATE TABLE . |
Comment | Комментарий, используемый при создании таблицы (или информация о том, почему MySQL не может обращаться к информации по данной таблицы). |
Таблицы InnoDB
сообщат свободное пространство в ней через
поле комментария таблицы.
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 | Число подключений, прерванных потому, что клиент не закрыл подключение правильно. Подробности в разделе "8.2.9 Ошибки связи/прерванные соединения". |
Aborted_connects | Число попыток соединиться с сервером MySQL, которые потерпели неудачу. Подробности в разделе "8.2.9 Ошибки связи/прерванные соединения". |
Bytes_received | Число байт, полученных с клиентов. |
Bytes_sent | Число байт, посланных клиентам. |
Connections | Число попыток подключения к серверу MySQL. |
Created_tmp_disk_tables | Число неявных временных таблиц на диске, созданных при выполнении инструкций. |
Created_tmp_tables | Число неявных временных таблиц в памяти, созданных при выполнении инструкций. |
Created_tmp_files | Сколько временных файлов
создал mysqld . |
Delayed_insert_threads | Число отсроченных потоков драйвера вставки в использовании. |
Delayed_writes | Число строк, записанных со
INSERT DELAYED . |
Delayed_errors | Число строк, записанных со
INSERT DELAYED , для которых произошла ошибка (вероятно, двойной
ключ (duplicate key ) был использован). |
Flush_commands | Число выполненных команд
FLUSH . |
Handler_delete | Сколько раз строка была удалена из таблицы. |
Handler_read_first | Сколько раз первая запись
читалась из индекса. Если это значение высоко, предполагается, что сервер
делал много полных просмотров индекса, например, SELECT col1 FROM
foo , считая, что col1 индексирован. |
Handler_read_key | Число запросов на чтение строки, основанных на ключе. Если это значение высоко, это значит, что Ваши запросы и таблицы были правильно индексированы. |
Handler_read_next | Число запросов на чтение следующей строки в порядке ключа. Это значение будет увеличено, если Вы запрашиваете индексный столбец с ограничением диапазона. Это также будет увеличено, если Вы делаете индексный просмотр. |
Handler_read_rnd | Число запросов на чтение строк, основанных на фиксированной позиции. Это значение будет высоким, если Вы делаете много запросов, которые требуют сортировки результата. |
Handler_read_rnd_next | Число запросов на чтение следующей строки в файле данных. Это значение будет высоким, если Вы делаете много просмотров таблицы. Вообще это предполагает, что Ваши таблицы не были правильно индексированы, или что Ваши запросы не используют индексы. |
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 | Число таблиц, которые были открыты. |
Select_full_join | Число объединений без ключей (должно быть 0). |
Select_full_range_join | Число объединений, где использовали поиск диапазона по таблице ссылок. |
Select_range | Число объединений, где использовали диапазоны в первой таблице. Это обычно не критическое, даже если это большое. |
Select_scan | Число объединений, где просмотрели первую таблицу. |
Select_range_check | Число объединений без ключей, где проверяем использование ключа после каждой строки (должно быть 0). |
Questions | Число запросов, посланных серверу. |
Slave_open_temp_tables | Число временных таблиц, в настоящее время открытых подчиненным процессом. |
Slow_launch_threads | Число потоков, которым
понадобилось для установления соединения больше, чем
slow_launch_time . |
Slow_queries | Число запросов, которые заняли
больше, чем long_query_time . Подробности в разделе
"4.9.5 Медленный файл регистрации".
|
Sort_merge_passes | Число объединений,
потребовавших сортировки. Если это значение большое, Вы должны рассмотреть
увеличение sort_buffer . |
Sort_range | Число сортировок с диапазонами. |
Sort_rows | Число сортируемых строк. |
Sort_scan | Число сортировок выполненных, просматривая таблицу. |
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_cache
,
вероятно, слишком маленькая. Коэффицент кэширования может быть вычислен по
формуле: key_reads
/key_read_requests
.
Handler_read_rnd
велико, то Вы, вероятно, имеете много
запросов, которые требуют, чтобы MySQL просматривал целые таблицы, или Вы
имеете объединения, которые не используют ключи правильно.
Threads_created
велико, то следует увеличить переменную
thread_cache_size
.SHOW VARIABLES
SHOW VARIABLES [LIKE wild]
SHOW VARIABLES
показывает значения некоторых переменных
системы MySQL. Вы можете также получить эту информацию, используя команду
mysqladmin variables
. Если значения по умолчанию неподходящие,
Вы можете устанавливать большинство этих переменных, используя параметры
командной строки mysqld
. Подробности в разделе
"
4.1.1 Параметры командной строки mysqld".
Вывод походит на показанное ниже, хотя формат и числа будут иными:
+-------------------------+---------------------------+ | Variable_name | Value | +-------------------------+---------------------------+ | ansi_mode | OFF | | back_log | 50 | | basedir | /my/monty/ | | bdb_cache_size | 16777216 | | bdb_log_buffer_size | 32768 | | bdb_home | /my/monty/data/ | | bdb_max_lock | 10000 | | bdb_logdir | | | bdb_shared_data | OFF | | bdb_tmpdir | /tmp/ | | binlog_cache_size | 32768 | | concurrent_insert | ON | | connect_timeout | 5 | | datadir | /my/monty/data/ | | delay_key_write | ON | | delayed_insert_limit | 100 | | delayed_insert_timeout | 300 | | delayed_queue_size | 1000 | | flush | OFF | | flush_time | 0 | | have_bdb | YES | | have_innodb | YES | | have_raid | YES | | have_ssl | NO | | init_file | | | interactive_timeout | 28800 | | join_buffer_size | 131072 | | key_buffer_size | 16776192 | | language | /my/monty/share/english/ | | large_files_support | ON | | log | OFF | | log_update | OFF | | log_bin | OFF | | log_slave_updates | OFF | | long_query_time | 10 | | low_priority_updates | OFF | | lower_case_table_names | 0 | | max_allowed_packet | 1048576 | | max_binlog_cache_size | 4294967295 | | 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_tmp_tables | 32 | | max_write_lock_count | 4294967295 | | myisam_recover_options | DEFAULT | | 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 | /my/monty/data/donna.pid | | port | 3306 | | protocol_version | 10 | | record_buffer | 131072 | | query_buffer_size | 0 | | safe_show_database | OFF | | server_id | 0 | | skip_locking | ON | | skip_networking | OFF | | skip_show_database | OFF | | slow_launch_time | 2 | | socket | /tmp/mysql.sock | | sort_buffer | 2097116 | | table_cache | 64 | | table_type | MYISAM | | thread_cache_size | 4 | | thread_stack | 65536 | | tmp_table_size | 1048576 | | tmpdir | /tmp/ | | version | 3.23.29a-gamma-debug | | wait_timeout | 28800 | +-------------------------+---------------------------+
Каждая опция описана ниже. Значения для буферных размеров, длин и размеров
стека даны в байтах. Вы можете определять значения с суффиксами
`K' или `M', чтобы указать килобайты или мегабайты.
Например, 16M
указывает 16 мегабайтов. Регистр символов суффикса
не имеет значения: 16M
и 16m
эквивалентны.
ansi_mode
.
ON
, если mysqld
запущен с опцией
--ansi
. Подробности в разделе
"1.2.3 Запуск MySQL в режиме ANSI".
back_log
back_log
указывает, сколько
запросов могут быть сложены в стек в течение этого короткого времени прежде,
чем MySQL на мгновение остановит ответы на новые запросы. Вы должны увеличить
это только, если Вы ожидаете большое количество подключений за короткий
периоде времени (сервер работает интенсивно).
Другими словами, это значение задает размер слушающей очереди для входящих
подключений TCP/IP. Ваша операционная система имеет собственное ограничение
размера этой очереди. В Unix man-страница listen(2)
должна
иметь большее количество деталей. Проверьте документацию на Вашу ОС для
выяснения максимального значения для этой переменной. Попытка устанавливать
back_log
выше, чем это ограничение операционной системы, будет
неэффективна, хотя и безопасна.
basedir
--basedir
.
bdb_cache_size
BDB
-таблиц. Если Вы не используете таблицы BDB
, Вы
должны запустить mysqld
с опцией --skip-bdb
, чтобы
не тратить впустую память для этого кэша.
bdb_log_buffer_size
BDB
-таблиц. Если Вы не используете таблицы BDB
, Вы
должны запустить mysqld
с опцией --skip-bdb
, чтобы
не тратить впустую память для этого кэша.
bdb_home
--bdb-home
.
bdb_max_lock
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
.
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
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
секунд все таблицы будут закрыты (чтобы освободить
ресурсы и сбросить данные на диск). Я рекомендую эту опцию только на Win95,
Win98 или на системах, где Вы имеете очень небольшое количество ресурсов.
have_bdb
YES
, если mysqld
поддерживает таблицы Berkeley
DB. DISABLED
, если использован параметр
--skip-bdb
.
have_innodb
YES
, если mysqld
поддерживает таблицы InnoDB.
DISABLED
, если использован параметр --skip-innodb
.
have_raid
YES
, если mysqld
поддерживает опцию
RAID
.
have_ssl
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
как раз и задает размер буфера, используемого
для индексных блоков. Увеличьте это значение, чтобы улучшить индексную
обработку. Но если Вы сделаете его слишком большим (больше, чем 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
. Подробности в разделе
"4.5.5 Синтаксис SHOW
".
Чтобы получить заметное ускорение при записи многих строк сразу,
используйте LOCK 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
, запрос будут регистрироваться в файле
регистрации медленных запросов. Подробности в разделе
"4.9.5 Медленный файл регистрации".
lower_case_table_names
max_allowed_packet
net_buffer_length
байт, но может вырасти до
max_allowed_packet
байт, когда необходимо. Это значение по
умолчанию маленькое, но позволяет захватывать большие (возможно,
неправильные) пакеты. Вы должны увеличить это значение, если используете
большие столбцы BLOB
. Он должно быть столь же большим как самый
крупный BLOB
, который Вы хотите использовать. Текущий протокол
ограничивает max_allowed_packet
размером 16M.
max_binlog_cache_size
max_binlog_size
max_connections
mysqld
.
Подробности в разделе "8.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
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
.
myisam_max_sort_file_size
REPAIR
,
ALTER TABLE
или LOAD DATA INFILE
. Если размер файла
больше, чем это значение, индекс будет создан через кэш ключа, который
является более медленным. ОБРАТИТЕ ВНИМАНИЕ, что этот
параметр задан в мегабайтах!
net_buffer_length
max_allowed_packet
байт.
net_read_timeout
write_timeout
. См. также
slave_read_timeout
.
net_retry_count
FreeBSD
, поскольку там внутренние прерывания посланы всем
серверным процессам чтения.
net_write_timeout
open_files_limit
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
record_buffer
record_rnd_buffer
record_buffer
.
query_buffer_size
safe_show_databases
skip_show_databases
.
server_id
--server-id
.
skip_locking
mysqld
использует внешнюю блокировку.
skip_networking
skip_show_databases
SHOW DATABASES
, если
пользователь не имеет привилегии PROCESS_PRIV
. Это может
улучшить защиту. См. также safe_show_databases
.
slave_read_timeout
slow_launch_time
Slow_launch_threads
будет увеличен.
socket
sort_buffer
ORDER BY
или GROUP BY
. Подробности в разделе
"8.4.4 Где MySQL хранит временные файлы
".
table_cache
mysqld
.
MySQL нуждается в двух описателях файла для каждой уникальной открытой
таблицы. Вы можете проверять, должны ли Вы увеличить кэш таблицы, анализируя
переменную Opened_tables
. Подробности в разделе
"4.5.5 Синтаксис SHOW
".
Удостоверьтесь, что Ваша операционная система может обрабатывать число
описателей файла, подразумеваемых установкой table_cache
. Если
table_cache
слишком велико, MySQL может исчерпать описатели
файла и начать сбоить. За информацией относительно того, как работает кэш
таблицы, отсылаю Вас к разделу "5.4.6 Как
MySQL открывает и закрывает таблицы".
table_type
thread_cache_size
thread_cache_size
потоков. Все новые потоки
сначала принимаются из кэша и только, когда кэш пуст, создаются новые. Эта
переменная может увеличиваться, чтобы улучшить эффективность, если Вы имеете
много новых подключений.
thread_concurrency
mysqld
вызовет thr_setconcurrency()
с этим значением. thr_setconcurrency()
разрешает прикладной
программе давать системе управления данные относительно желательного числа
потоков, которые должны быть выполнены в одно и то же время.
thread_stack
crash-me
, зависят от этого значения. Значение по
умолчанию достаточно большое для нормальной работы. Подробности в разделе
"5.1.4 Пакет тестов
MySQL Benchmark Suite".
timezone
tmp_table_size
MyISAM
на диске.
Увеличьте значение tmp_table_size
, если Вы делаете много
продвинутых запросов GROUP BY
, и Вы имеете много памяти.
tmpdir
version
wait_timeout
interactive_timeout
.Раздел, который описывает настройку MySQL, содержит некоторую информацию относительно того, как настроить вышеупомянутые переменные. Подробности смотрите в разделе "5.5.2 Настройка параметров сервера".
SHOW LOGS
SHOW LOGS
показывает Вам информацию относительно состояния
существующих журналов. В настоящее время этот вызов отображает только
информацию относительно журналов Berkeley DB.
File
показывает полный путь к журналу.
Type
показывает тип журнала (BDB
для журналов
типа Berkeley DB).
Status
показывает состояние журнала (FREE
если
файл может быть удален, или IN USE
если файл необходим
подсистеме транзакций).SHOW PROCESSLIST
SHOW PROCESSLIST
показывает Вам, которые процессы работают.
Вы можете также получать эту информацию, используя команду mysqladmin
processlist
. Если Вы имеете привилегию process, Вы
можете видеть все процессы. Иначе Вы можете видеть только Ваши собственные
процессы. Если Вы не используете опцию FULL
, то только первые
100 символов каждого запроса будут показаны. Подробности в разделе
"4.5.4 Синтаксис KILL
".
Эта команда очень полезна, если Вы получаете сообщения об ошибках 'too
many connections' и хотите выяснить, что происходит. MySQL резервирует одно
подключение дополнительно для пользователя с привилегией
Process_priv
, чтобы гарантировать, что Вы всегда способны ко
входу в систему и ее проверке (эта ситуация не дает такую же привилегию всем
Вашим пользователям).
SHOW GRANTS
SHOW GRANTS FOR user
вносит в список команды, который должны
быть выданы, чтобы дублировать права пользователя. Например:
mysql> SHOW GRANTS FOR root@localhost; +---------------------------------------------------------------------+ | Grants for root@localhost | +---------------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION | +---------------------------------------------------------------------+
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
. Подробности в разделе
"5.5.6 Синтаксис SET
".
Вся клиентура MySQL, которая связывается с сервером, используя библиотеку
mysqlclient
, применяет следующие системные переменные:
Имя | Описание |
MYSQL_UNIX_PORT | Сокет по умолчанию. Используется
для связи с localhost |
MYSQL_TCP_PORT | Порт TCP/IP по умолчанию |
MYSQL_PWD | Пароль по умолчанию |
MYSQL_DEBUG | Опции трассировки при отладке |
TMPDIR | Каталог для хранения временных таблиц и файлов для свопа |
Использование MYSQL_PWD
может нарушить безопасность системы!
Подробности в разделе "4.2.7
Связь с сервером MySQL".
Клиент mysql использует файл, заданный в переменной окружения
MYSQL_HISTFILE
, чтобы сохранить хронологию командной строки.
Значение по умолчанию для файла хронологии $HOME/.mysql_history, где
$HOME
значение системной переменной HOME
, что
позволяет хранить историю команд отдельно для каждого пользователя.
Подробности в разделе "
Приложение 2. Переменные окружения".
Все программы MySQL берут много различных параметров. Однако, каждая
программа MySQL обеспечивает опцию справки --help
, это Вы можете
использовать, чтобы получить полное описание различных параметров программы.
Например, попробуйте вызов mysql --help
.
Вы можете отменять заданные по умолчанию параметры для всех стандартных программ клиентов файлом опций. Подробности в разделе "4.1.2 Файл опций my.cnf".
Список ниже кратко описывает программы MySQL:
myisamchk
myisamchk
имеет много функций, он описан в
собственном разделе.
make_binary_distribution
support.mysql.com
для удобства других пользователей MySQL.
msql2mysql
mSQL
в программы для
MySQL. Это не обрабатывает все случаи, но дает хорошее начало при
преобразовании.
mysqlaccess
mysqladmin
mysqladmin
может также использоваться, чтобы
получить данные о версии, процессах и статусе сервера. Подробности в разделе
"4.8.3
mysqladmin, Администрирование сервера MySQL".
mysqlbug
mysqld
mysqldump
mysqlimport
LOAD DATA INFILE
. Подробности в разделе
"4.8.7 mysqlimport, Импорт данных
из текстовых файлов".
mysqlshow
mysql_install_db
replace
msql2mysql
, но она имеет более
общее назначение. replace
заменяет строки в файлах или на
стандартном вводе. Может использоваться, чтобы переставлять строки местами.
Например, эта команда меняет в заданных файлах a
и
b
:
shell> replace a b b a -- file1 file2 ...
safe_mysqld
рекомендуемый способ запуска mysqld
сервера на Unix. safe_mysqld
добавляет некоторые свойства
безопасности типа перезапуска сервера, когда происходит ошибка, и регистрации
информации времени выполнения в журнале.
Если Вы не используете параметры --mysqld=#
или
--mysqld-version=#
, safe_mysqld
использует
программу с именем mysqld-max
, если она существует. В противном
случае safe_mysqld
запустит mysqld
.
Обычно никогда нельзя редактировать скрипт safe_mysqld
,
вместо этого надо помещать параметры в раздел [safe_mysqld]
в
файле my.cnf
. Скрипт safe_mysqld
будет читать все
параметры из секций [mysqld]
, [server]
и
[safe_mysqld]
. Подробности в разделе
"4.1.2 Файл опций my.cnf".
Обратите внимание, что все параметры в командной строке
safe_mysqld
передаются mysqld
. Если Вы хотите в
safe_mysqld
использовать параметры, которые не понимает
mysqld
, Вы должны определить их в файле опций.
Большинство параметров safe_mysqld
также представляют собой и
параметры для mysqld
. Подробности в разделе
"4.1.1 Параметры командной строки
mysqld".
safe_mysqld
поддерживает следующие параметры:
--basedir=path
--core-file-size=#
mysqld
должен быть способен создать.
Используйте ulimit -c
.
--datadir=path
, --defaults-extra-file=path
,
--defaults-file=path
, --err-log=path
,
--ledir=path
, --log=path
,
--pid-file=path
mysqld
.
--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, чтобы это работало правильно!
--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
из
соответствующего ему каталога:
shell> cd mysql_installation_directory shell> bin/safe_mysqld &
Если safe_mysqld
не может ничего сделать, даже когда
вызывается из каталога MySQL, Вы можете использовать путь для
mysqld
, который является правильным для Вашей системы. Обратите
внимание, что, если Вы проапгрейдите MySQL, создастся новый файл
safe_mysqld
, и проблема вернется. Так что зарезервируйте
правильную версию стартового скрипта и восстановите ее после апгрейда.
mysqld_multi
предполагается для управления несколькими
серверами mysqld
на разных сокетах UNIX и портах TCP/IP.
Программа будет искать группу по именем вида [mysqld#] в файле my.cnf (или
в том файле настроек, который задан опцией --config-file=...), где # может
быть любым положительным номером, начиная с 1. Эти группы должны быть такими
же, как обычная группа [mysqld]
, но с тем портом, сокетом и
прочими специфическими данными, которые требуются для отдельных процессов
mysqld
. Номер в имени группы имеет другую функцию; он может
использоваться для старта, остановки или связи с этой программой.
Usage: mysqld_multi [OPTIONS] {start|stop|report} [GNR,GNR,GNR...] or mysqld_multi [OPTIONS] {start|stop|report} [GNR-GNR,GNR,GNR-GNR,...]
GNR означает номер группы. Вы можете запускать, останавливать или менять любой GNR или несколько из них в то же самое время. Список GNRS может быть разделен запятой или тире. Последнее означает диапазон воздействия GNR1-GNR2. Без параметра GNR все найденные группы будут обработаны. Обратите внимание, что Вы не должны иметь никаких пробелов в перечне GNR. Все после первого же пробела игнорируется вообще.
mysqld_multi
поддерживает следующие опции:
--config-file=...
[mysqld_multi]
), а только на группы [mysqld#]. Без этой опции
все будет взято из обычного файла my.cnf.
--example
--help
--log=...
--mysqladmin=...
mysqladmin
(используется для закрытия системы).
--mysqld=...
mysqld
. Обратите внимание, что Вы можете указать
здесь и safe_mysqld
. Параметры будут переданы
mysqld
. Только удостоверьтесь, что Вы имеете mysqld
в Вашей системной переменной PATH
или поправили
safe_mysqld
.
--no-log
--password=...
mysqladmin
.
--tcp-ip
--user=...
mysqladmin
.
--version
Некоторые замечания относительно mysqld_multi
:
mysqld
(то есть, пользуется mysqladmin
) имеет тот
же самый пароль и логин для всех каталогов данных, к которым обращается.
Также надо проверить, что пользователь имеет привилегию Shutdown_priv! Если
Вы имеете много данных и много различных баз данных mysql с различными
паролями для MySQL-пользователя root, Вы можете создать общего пользователя
multi_admin:
shell> mysql -u root -S /tmp/mysql.sock -proot_password -e "GRANT SHUTDOWN ON *.* TO multi_admin@localhost IDENTIFIED BY 'multipass'"
pid-file
очень важен, если Вы используете
safe_mysqld
, чтобы запустить mysqld
(например,
--mysqld=safe_mysqld). Каждый mysqld
должен иметь собственный
pid-file
. Перимущество применения здесь safe_mysqld
вместо mysqld
в том, что safe_mysqld
присматривает
за процессом mysqld
и перезапустит его в случае падения.
Пожалуйста, обратите внимание, что скрипт 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 --------------------------------------------------------------------------
mysqld
из одного каталога, они передерутся!
mysqld
.
mysqld
будут обрабатываться в
порядке их обнаружения в файле настройки.
mysqld
, но
чтобы делать это, Вы должны быть root, когда запускаете скрипт
mysqld_multi
. Наличие опции в файле конфигурации не имеет
значение. Вы только получите предупреждение, если Вы не суперпользователь, и
mysqld
стартует под ВАШИМ логином в UNIX.
ВАЖНО: Удостоверьтесь, что каталог данных и pid-файл
читаются и пишутся для ЭТОГО пользователя UNIX!
mysqlds
, и почему Вы
хотите использовать отдельные процессы mysqld
.
Запуск нескольких серверов в одном каталоге баз данных выигрыша в скорости
НЕ ДАСТ НИКОГДА!Подробности в разделе "4.1.4 Запуск нескольких серверов MySQL на одной системе".
Пример файла конфигурации mysqld_multi
.
# This file should probably be in your home dir (~/.my.cnf) or /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
myisampack
используется, чтобы сжать MyISAM таблицы, а
pack_isam
используется, чтобы сжать ISAM таблицы. Поскольку
таблицы системы ISAM считаются устаревшими, здесь будет рассмотрен только
myisampack
, но все сказанное применимо и для
pack_isam
.
myisampack
работает, сжимая каждый столбец в таблице отдельно.
Информация, необходимая для распаковки, читается в память, когда таблица
открывается. Это приводит к резкому улучшению эффективности при доступе к
одиночным записям. Дело в том, что расжимать приходится только одну запись, а
не большой дисковый блок, как при использовании Stacker в MS-DOS. Обычно
myisampack
упаковывает файл данных на 40%-70%.
MySQL использует управление памятью (mmap()
) на сжатых
таблицах и возвращается обратно к нормальному использованию файла для чтения
и записи, если mmap()
не работает.
В настоящее время имеются два ограничения для myisampack
:
myisampack
может также упаковывать столбцы BLOB
или TEXT
. Старая программа pack_isam
делать этого,
увы, не умеет.Снятие этих ограничений находится в списке TODO, но с низким приоритетом.
myisampack
вызывается примерно так:
shell> myisampack [options] 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
, файл `.TMD' не может быть удален. Обычно
myisampack
завершается с ошибкой, если находит, что файл
`tbl_name.TMD' существует. С опцией --force
myisampack
упаковывает таблицу всегда.
-?, --help
-j big_tbl_name, --join=big_tbl_name
big_tbl_name
. Все таблицы, которые должны быть
объединены, ДОЛЖНЫ БЫТЬ идентичны (те же самые имена столбца и типы, те же
самые индексыи т.д.).
-p #, --packlength=#
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-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
empty-zero
empty-fill
INTEGER
может быть изменен на MEDIUMINT
).
pre-space
end-space
table-lookup
ENUM
перед сжатием Huffman.
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
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
.
mysqld-max
представляет собой сервер MySQL
(mysqld
), собранный со следующими параметрами конфигурации:
Опция | Комментарий |
--with-server-suffix=-max | Добавлять суффикс к строке версии
mysqld . |
--with-bdb | Поддерживать таблицы Berkeley DB (BDB) |
--with-innodb | Поддерживать таблицы InnoDB. |
CFLAGS=-DUSE_SYMDIR | Поддерживать ссылки для Windows. |
Вы можете скачать бинарники MySQL-max с координат: http://www.mysql.com/downloads/mysql-max-3.23.html.
Двоичный дистрибутив (не исходники!) Windows MySQL 3.23 включает
стандартный mysqld.exe
и расширенный
mysqld-max.exe
. Скачать можно с координат:
http://www.mysql.com/downloads/mysql-3.23.html. Подробности в разделе
"2.1.2 Установка MySQL в Windows
".
Обратите внимание, что, так как Berkeley DB и InnoDB не доступны для всех
платформ, некоторые из двоичных версий Max
могут и не иметь
поддержку их обоих. Вы можете проверять, какие типы таблицы поддержаны,
делая следующий запрос:
mysql> show variables like "have_%"; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | have_bdb | YES | | have_innodb | NO | | have_isam | YES | | have_raid | NO | | have_ssl | NO | +---------------+-------+
Смысл значений:
Значение | Смысл. |
YES | Опция активизирована и пригодна для использования. |
NO | MySQL не компилируется с поддержкой для этой опции. |
DISABLED | Опция xxxx заблокирована, потому что
mysqld запущен с опцией --skip-xxxx , или, наоборот,
mysqld не получил всех необходимых параметров, чтобы включить
поддержку опции. В этом случае файл hostname.err должен
содержать причину того, почему опция заблокирована. |
ОБРАТИТЕ ВНИМАНИЕ: Чтобы создавать таблицы InnoDB, Вы
ДОЛЖНЫ редактировать Ваши параметры запуска, чтобы включить
по крайней мере опцию innodb_data_file_path
. Подробности в
разделе "7.6.2 Опции запуска InnoDB".
Чтобы получать лучшую эффективность для таблиц BDB, Вы также должны добавить некоторые параметры конфигурации для них. Подробности в разделе "7.5.3 Опции запуска BDB".
safe_mysqld
автоматически пробует запускать любой двоичный
исполняемый модуль mysqld
с префиксом -max
.
mysqld-max
RPM использует вышеупомянутое свойство
safe_mysqld
. Он только устанавливает выполнимую программу
mysqld-max
, а safe_mysqld
автоматически использует
эту выполнимую программу, когда будет перезапущен.
Следующая таблица показывает, какие таблицы поддерживаются MySQL-Max для разных платформ:
Система | BDB | InnoDB |
AIX 4.3 | N | Y |
HP-UX 11.0 | N | Y |
Linux-Alpha | N | Y |
Linux-Intel | Y | Y |
Linux-Ia64 | N | Y |
Solaris-Intel | N | Y |
Solaris-Sparc | Y | Y |
SCO OSR5 | Y | Y |
Unix Ware | Y | Y |
Windows NT | Y | Y |
Все перечисленные в книге программы доступны в сети. Поэтому первоначально
я не мог решить, нужно ли создавать сопроводительный CD-ROM. Но потом я
убедился, что поиск в сети всех необходимых пакетов, а главное, их скачивание
на свой
Все архивы на диске поставляются в форматах Tar+Gzip и RPM, принятых в Linux и вообще почти всех Unix-системах. Основная масса архивов взята мной с сайта разработчиков MySQL. Диск охватывает все возможные дистрибутивы и дополнения к ним, которые официально представлены для этого пакета.
ВСЕ ПРОГРАММЫ НА СОПРОВОДИТЕЛЬНОМ CD-ROM ВЗЯТЫ МНОЙ ИЗ ОТКРЫТЫХ СЕТЕВЫХ ИСТОЧНИКОВ И РАСПРОСТРАНЯЮТСЯ В СТРОГОМ СООТВЕТСТВИИ С ИХ ЛИЦЕНЗИЯМИ. ДИСК НЕ СОДЕРЖИТ ПИРАТСКИХ КОПИЙ КАКОГО БЫ ТО НИ БЫЛО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ. ОСНОВНАЯ ЧАСТЬ ПРОГРАММ НА НЕМ ПОСТАВЛЯЕТСЯ В ИСХОДНЫХ ТЕКСТАХ.
Имеется список всех системных переменных, которые используются MySQL непосредственно или косвенно. Большинство их также может быть найдено в других местах в этом руководстве.
Обратите внимание, что любые параметры в командной строке будут иметь приоритет над значениями, определенными в файлах конфигурации и системных переменных, а значения в файлах конфигурации всегда имеют приоритет над значениями в системных переменных.
Во многих случаях предпочтительно использовать файл выбора конфигурации вместо системных переменных, чтобы изменить поведение MySQL. Подробности в разделе "4.1.2 Файл опций my.cnf".
DBI_USER | Заданный по умолчанию пользователь для интерфейса Perl DBI. |
DBI_TRACE | Используется при трассировке Perl DBI. |
HOME | Заданный по умолчанию путь для файла
хронологии mysql , обычно $HOME/.mysql_history. |
LD_RUN_PATH | Используется, чтобы определить, где
находится Ваша библиотека libmysqlclient.so . |
MYSQL_DEBUG | Опции трассировки при отладке. |
MYSQL_HISTFILE | Путь к файлу хронологии
mysql . |
MYSQL_HOST | Заданное по умолчанию имя хоста,
используемое подсказкой командной строки mysql . |
MYSQL_PWD | Заданный по умолчанию пароль при
соединении с mysqld . Обратите внимание, что использование этой
возможности задания пароля опасно! |
MYSQL_TCP_PORT | Заданный по умолчанию порт TCP/IP. |
MYSQL_UNIX_PORT | Сокет по умолчанию. Используется
для связи с localhost . |
PATH | Используется оболочкой для поиска программ и утилит пакета MySQL. |
TMPDIR | Каталог, где будут созданы временные таблицы или файлы. |
TZ | Это должно быть установлено в Вашу зону местного времени. Подробности в разделе "8.4.6 Проблемы часового пояса". |
UMASK_DIR | Создание каталога пользователя будет
выполнено с данной маской прав доступа. Обратите внимание, что это значение
будет использовано в операции AND с UMASK ! |
UMASK | То же самое, но для создания файлов. |
USER | Заданный по умолчанию пользователь в
Windows, чтобы использовать при соединении с mysqld . |
Регулярные выражения (они же regular expression или regex) представляют собой мощный путь для определения сложного поиска.
MySQL использует реализацию Henry Spencer's, которая нацелена на соответствие POSIX 1003.2. MySQL использует ее расширенную версию.
Это упрощенное описание, которое опускает ряд деталей. За подробной
информацией отсылаю Вас к man-странице Henry Spencer's regex(7)
,
которая включена в дистрибутив исходного кода.
Регулярное выражение описывает набор строк. Самый простой regexp такой,
который не имеет никаких специальных символов. Например, regexp
hello
соответствует hello
и ничему другому.
Нетривиальные регулярные выражения используют некоторые специальные
конструкции так, чтобы они могли соответствовать больше, чем одной строке.
Например, regexp hello|word
соответствует строке
hello
или word
.
Как более сложный пример, regexp B[an]*s
соответствует любой
из строк Bananas
, Baaaaas
, Bs
и любой
другой строке, начинающейся с B
, заканчивающейся на
s
и содержащей любое число символов в диапазоне от
a
до n
между ними.
Регулярное выражение может использовать любой из следующих спецсимволов:
^
mysql> select "fo\nfo" REGEXP "^fo$"; -> 0 mysql> select "fofo" REGEXP "^fo"; -> 1
$
mysql> select "fo\no" REGEXP "^fo\no$"; -> 1 mysql> select "fo\no" REGEXP "^fo$"; -> 0
.
mysql> select "fofo" REGEXP "^f.*"; -> 1 mysql> select "fo\nfo" REGEXP "^f.*"; -> 1
a*
a
.
mysql> select "Ban" REGEXP "^Ba*n"; -> 1 mysql> select "Baaan" REGEXP "^Ba*n"; -> 1 mysql> select "Bn" REGEXP "^Ba*n"; -> 1
a+
a
.
mysql> select "Ban" REGEXP "^Ba+n"; -> 1 mysql> select "Bn" REGEXP "^Ba+n"; -> 0
a?
a
.
mysql> select "Bn" REGEXP "^Ba?n"; -> 1 mysql> select "Ban" REGEXP "^Ba?n"; -> 1 mysql> select "Baan" REGEXP "^Ba?n"; -> 0
de|abc
de
или abc
.
mysql> select "pi" REGEXP "pi|apa"; -> 1 mysql> select "axe" REGEXP "pi|apa"; -> 0 mysql> select "apa" REGEXP "pi|apa"; -> 1 mysql> select "apa" REGEXP "^(pi|apa)$"; -> 1 mysql> select "pi" REGEXP "^(pi|apa)$"; -> 1 mysql> select "pix" REGEXP "^(pi|apa)$"; -> 0
(abc)*
abc
.
mysql> select "pi" REGEXP "^(pi)*$"; -> 1 mysql> select "pip" REGEXP "^(pi)*$"; -> 0 mysql> select "pipi" REGEXP "^(pi)*$"; -> 1
{1}
{2,3}
a*
a{0,}
.
a+
a{1,}
.
a?
a{0,1}
.i
без запятой соответствует последовательности точно
i
вхождений атома. Атом, сопровождаемый одним числом с запятой,
соответствует последовательности из одного или большего числа вхождений
i
. Атом, сопровождаемый двумя целыми числами i
и
j
соответствует последовательности, включающей от i
до j
копий атома (границы диапазона входят в число). Оба
аргумента должны быть в диапазоне от 0
до
RE_DUP_MAX
(по умолчанию 255), включая границы. Если заданы два
аргумента, второй должен быть больше или равен первому, но не меньше его.
[a-dX]
[^a-dX]
a
, b
, c
,
d
или X
. Чтобы включить литеральный символ
]
, он должен следовать сразу за открывающейся скобкой
[
. Чтобы включить символ -
, он должен быть написан
первым или последним. Так [0-9]
соответствует любой десятичной
цифре. Любой символ, который не имеет определенного значения внутри
[]
, не имеет никакого специального значения.
mysql> select "aXbc" REGEXP "[a-dXYZ]"; -> 1 mysql> select "aXbc" REGEXP "^[a-dXYZ]$"; -> 0 mysql> select "aXbc" REGEXP "^[a-dXYZ]+$"; -> 1 mysql> select "aXbc" REGEXP "^[^a-dXYZ]+$"; -> 0 mysql> select "gheis" REGEXP "^[^a-dXYZ]+$"; -> 1 mysql> select "gheisa" REGEXP "^[^a-dXYZ]+$"; -> 0
[[.characters.]]
ch
, то регулярное выражение [[.ch.]]*c
соответствует первым пяти символам chchcc
.
[=character_class=]
o
и (+)
члены класса
эквивалентности, то [[=o=]]
, [[=(+)=]]
и
[o(+)]
синонимы. Класс эквивалентности не может
быть краем диапазона.
[:character_class:]
[:
и :]
, представляет список всех символов,
принадлежащих к классу. Стандартные символьные имена:
alnum | digit | punct |
alpha | graph | space |
blank | lower | upper |
cntrl | xdigit |
ctype(3)
. Регион или язык может обеспечивать другие. Символьный
класс не может использоваться как край диапазона.
mysql> select "justalnums" REGEXP "[[:alnum:]]+"; -> 1 mysql> select "!!" REGEXP "[[:alnum:]]+"; -> 0
[[:<:]]
[[:>:]]
ctype(3)
) или символов подчеркивания
(_
).
mysql> select "a word a" REGEXP "[[:<:]]word[[:>:]]"; -> 1 mysql> select "a xword a" REGEXP "[[:<:]]word[[:>:]]"; -> 0
mysql> select "weeknights" REGEXP "^(wee|week)(knights|nights)$"; -> 1
Version 2, June 1991
Copyright © 1989, 1991 Free Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and modification follow.
9.4 NO WARRANTY
If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the ``copyright'' line and a pointer to where the full notice is found.
one line to give the program's name and a brief idea of what it does. Copyright (C) yyyy name of author This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
The hypothetical commands show w and show c should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than show w and show c; they could even be mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your school, if any, to sign a ``copyright disclaimer'' for the program, if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice
This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.
Version 2.1, February 1999
Copyright © 1991, 1999 Free Software Foundation, Inc. 59 Temple Place -- Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.]
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some specially designated software--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.
To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.
Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.
When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.
We call this license the Lesser General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.
For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.
Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a ``work based on the library'' and a ``work that uses the library''. The former contains code derived from the library, whereas the latter must be combined with the library in order to run.
9.6 NO WARRANTY
If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).
To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the ``copyright'' line and a pointer to where the full notice is found.
one line to give the library's name and an idea of what it does. Copyright (C) year name of author This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your school, if any, to sign a ``copyright disclaimer'' for the library, if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. signature of Ty Coon, 1 April 1990 Ty Coon, President of Vice
That's all there is to it!
Поддержка для таблиц BDB включена в исходники MySQL начиная с версии 3.23.34 и активизирована в двоичной версии MySQL-Max.
BerkeleyDB, доступные по адресу
http://www.sleepycat.com обеспечивают MySQL транзакционным драйвером
таблицы. Используя BerkeleyDB, Ваши таблицы могут иметь большую возможность
выживания после сбоев, а также обеспечивать COMMIT
и
ROLLBACK
на транзакциях. В дистрибутив исходников MySQL входит
комплект исходников BDB с несколькими патчами для обеспечения работы с MySQL.
Непропатченную версию BDB
использовать вместе с MySQL нельзя.
Если Вы загрузили двоичную версию MySQL, которая включает поддержку для BerkeleyDB, надо просто следовать командам для установки двоичной версии MySQL. Подробности в разделе "4.7.5 mysqld-max, расширенный сервер mysqld".
Чтобы компилировать MySQL с поддержкой Berkeley DB, загрузите MySQL
Version 3.23.34 или более новую и сконфигурируйте MySQL
с
опцией --with-berkeley-db
. Подробности в разделе
"2.3 Установка исходников MySQL".
cd /path/to/source/of/mysql-3.23.34 ./configure --with-berkeley-db
Пожалуйста, обратитесь к руководству, предоставленному дистрибутивом
BDB
для получения более подробной информации.
Даже при том, что Berkeley DB сам по себе очень проверен и надежен, интерфейс с MySQL все еще рассматривается в качестве бета-версии. Но он активно улучшается и отлаживается.
Если Вы работаете с AUTOCOMMIT=0
, изменения в таблицах
BDB
не будут восприниматься, пока Вы не выполните
COMMIT
. Вместо этого можно выполнить ROLLBACK
,
чтобы забыть Ваши изменения.
Если Вы работаете с AUTOCOMMIT=1
(значение по умолчанию),
Ваши изменения будут совершены немедленно. Вы можете запустить расширенную
транзакцию с помощью вызова SQL BEGIN WORK
, после которой Ваши
изменения не будут внесены в таблицу до тех пор, пока Вы не выполните
COMMIT
(или ROLLBACK
для отмены изменений).
Следующие параметры mysqld
могут использоваться, чтобы
изменить поведение BDB таблиц:
Опция | Что она делает |
--bdb-home=directory | Базовый каталог для таблиц BDB. Может совпадать с именем, указанным в --datadir. |
--bdb-lock-detect=# | Определение блокировок по Berkeley. Допустимы значения: DEFAULT, OLDEST, RANDOM или YOUNGEST. |
--bdb-logdir=directory | Каталог для файлов протоколирования Berkeley DB. |
--bdb-no-sync | Не синхронизировать сброс протоколов. |
--bdb-no-recover | Не запускать Berkeley DB в режиме восстановления. |
--bdb-shared-data | Запускать Berkeley DB в
многопроцессном режиме (не используйте DB_PRIVATE при
установке Berkeley DB). |
--bdb-tmpdir=directory | Имя временного файла Berkeley DB. |
--skip-bdb | Не использовать поддержку berkeley db. |
-O bdb_max_lock=1000 | Установить максимальное
число допустимых блокировок. Подробности в разделе
"4.5.5.4 Синтаксис SHOW VARIABLES
". |
Если Вы использовали опцию --skip-bdb
, MySQL не будет
инициализировать библиотеку Berkeley DB, что лишит возможности использовать
таблицы BDB
, но зато сэкономит немало памяти.
Обычно Вы должны запустить mysqld
без опции
--bdb-no-recover
, если Вы предполагаете использовать
BDB-таблицы. Это, однако, может создавать Вам проблемы, когда Вы пробуете
запускать mysqld
, если BDB журналы разрушены.
С помощью опции bdb_max_lock
Вы можете определять
максимальное число блокировок (10000 по умолчанию), которые можно иметь
активными на BDB-таблице. Вы должны увеличить это число, если получаете
ошибки типа bdb: Lock table is out of available locks
или
Got error 12 from ...
, когда Вы делаете длинные транзакции, или
если mysqld
должен исследовать очень много строк, чтобы
вычислить результат запроса.
Вы можете также изменять binlog_cache_size
и
max_binlog_cache_size
, если Вы используете большие транзакции.
BDB
--bdb_log_dir
.
FLUSH LOGS
в любое время для
создания контрольной точки таблицы Berkeley DB. Для восстановления нужно
использовать копии таблицы плюс двоичный файл регистрации MySQL. Подробности
в разделе "4.4.1 Резервирование баз данных".
Предупреждение: Если Вы удаляете старые журналы, которые
еще находятся в использовании, BDB не будет способен делать восстановление
вообще, и Вы можете потерять данные, если что-то пойдет неправильно.
PRIMARY KEY
в каждой BDB-таблице, чтобы
предварительно читать строки. Если Вы не создаете ключ, MySQL сам создаст
поддерживающий скрытый PRIMARY KEY
для Вас. Скрытый ключ имеет
длину 5 байт и будет увеличен для каждой попытки вставки.
BDB
,
представляют собой часть того же самого индекса или части первичного ключа,
то MySQL может выполнять запрос без того, чтобы обращаться к фактической
строке. В таблице MyISAM
вышеупомянутое верно только, если
столбцы представляют собой часть того же самого индекса.
PRIMARY KEY
будет быстрее, чем любой другой ключ, поскольку
PRIMARY KEY
сохранен вместе с данными строки. Поскольку другие
ключи сохранены как данные ключа+PRIMARY KEY
, важно держать
PRIMARY KEY
максимально коротким, что сэкономит место на диске.
LOCK TABLES
работает на таблицах BDB
так же,
как и с другими таблицами. Если Вы не используете LOCK TABLE
,
MYSQL выдаст внутреннюю блокировку многократной записи на таблице, чтобы
гарантировать, что таблица будет правильно блокирована, если другой процесс
выдает блокировку таблицы.
BDB
выполнена
на уровне страницы.
SELECT COUNT(*) FROM table_name
работает медленно на
таблицах BDB
, поскольку BDB таблицы не поддерживают счетчик
числа строк в таблице.
MyISAM
,
поскольку данные в BDB-таблицах, сохранены в B-деревьях, а не в
отдельном файле данных.
BDB
может вызвать автоматическую
обратную перемотку, а любое чтение может терпеть неудачу с ошибкой тупика.
BDB
в сравнении с соответствующими таблицами MyISAM,
которые не используют PACK_KEYS=0
.
DELETE
или ROLLBACK
, это число должно быть
достаточно точным для оптимизатора MySQL, но поскольку MySQL сохраняет его
только на завершении, может быть неправильно, если MySQL свалится неожиданно.
Не должно быть фатально, если это число не 100%-но правильно. Можно
модифицировать число строк выполнением ANALYZE TABLE
или
вызовом OPTIMIZE TABLE
.
BDB
, Вы
получите ошибку (вероятно, ошибку с кодом 28), и транзакция должна быть
отменена. Это отличие от таблиц MyISAM
и ISAM
, где
mysqld
будет ждать достаточного свободного места на диске перед
продолжением выполнения транзакции.--no-auto-rehash
при вызове клиентов mysql
. Планируется исправить к версии 4.0.
SHOW TABLE STATUS
не обеспечивает много полезной информации
для BDB-таблиц.
Если Вы, сформировав MySQL с поддержкой для BDB-таблиц, получаете
следующую ошибку в журнале, когда Вы запускаете mysqld
:
bdb: architecture lacks fast mutexes: applications cannot be threaded Can't init dtabases
Это означает, что таблицы BDB
пока не поддержаны для Вашей
архитектуры. В этом случае Вы должны восстановить MySQL без поддержки таблиц
BDB
.
ОБРАТИТЕ ВНИМАНИЕ: следующий список не полон, разработчики его модифицируют, поскольку получают большое количество информации о проблемах.
На сегодняшний день таблицы BDB работают под следующими ОС:
На сегодняшний день таблицы BDB НЕ работают под следующими ОС:
hostname.err
при запуске mysqld
:
bdb: Ignoring log file: .../log.XXXXXXXXXX: unsupported log version #Это означает, что новая версия
BDB
не поддерживает старый формат
журнала. В этом случае Вы должны удалить протоколы BDB
из Вашего
каталога баз данных (файлы, которые имеют имена в формате
log.XXXXXXXXXX
) и перезапустить mysqld
. Советую
также выполнить для Ваших старых BDB
-таблиц команду
mysqldump --opt
, удалить их и восстановить из дампа.
auto_commit
и удаляете
таблицу, используемую другим процессом, Вы можете получать следующие
сообщения об ошибках в файле регистрации ошибок MySQL:
001119 23:43:56 bdb: Missing log fileid entry 001119 23:43:56 bdb: txn_abort: Log undo failed for LSN: 1 3644744: InvalidЭто не фатально, но я не рекомендую проводить такие эксперименты над Вашей системой, пока эта проблема не будет исправлена разработчиками.
Программа mysqld
понимает параметры командной строки:
--ansi
-b, --basedir=path
--big-tables
--bind-address=IP
--character-sets-dir=path
--chroot=path
mysqld
. Немного ограничит
LOAD DATA INFILE
и SELECT ... INTO OUTFILE
.
--core-file
mysqld
сваливается. Для некоторых
систем Вы должны также определить --core-file-size
в скрипте
safe_mysqld
.
-h, --datadir=path
--default-character-set=charset
--default-table-type=type
--debug[...]=
--with-debug
, Вы можете
использовать эту опцию, чтобы получить файл трассировки того, что делает
mysqld
.
--delay-key-write-for-all-tables
MyISAM
.
--enable-locking
-T, --exit-info
--flush
-?, --help
--init-file=file
-L, --language=...
-l, --log[=file]
--log-isam[=file]
--log-slow-queries[=file]
long_query_time
секунд в файле file.
--log-update[=file]
file.#
, где
#
является уникальным числом, если не задан.
--log-long-format
--log-slow-queries
, то запросы, которые не
используют индексы, регистрируются в медленном файле регистрации.
--low-priority-updates
INSERT
/DELETE
/UPDATE
) будут иметь
более низкий приоритет, чем выбор из таблицы. Это может также быть выполнено
через {INSERT | REPLACE | UPDATE | DELETE} LOW_PRIORITY ...
,
чтобы понизить приоритет только относительно одного запроса, или
SET OPTION SQL_LOW_PRIORITY_UPDATES=1
, чтобы изменить приоритет
в одном конкретном потоке.
--memlock
mysqld
в памяти. Это работает только,
если Ваша система поддерживает системный вызов mlockall()
(подобно Solaris). Это может помочь, если Вы имеете проблему, где
операционная система заставляет mysqld
свопиться на диск.
--myisam-recover [=option[,option...]]]
DEFAULT
,
BACKUP
, FORCE
или QUICK
. Вы можете
также устанавливать это в ""
, если Вы хотите отключить эту
опцию. Если эта опция используется, mysqld
при открытии будет
проверять отмечена ли таблица как поврежденная или не закрытая правильно
(последняя опция работает только, если Вы запустили пакет с параметром
--skip-locking
). Если таблица была разрушена,
mysqld
попробует ее починить. Следующие параметры воздействуют
на ремонтные работы.
DEFAULT | Аналогично опции --myisam-recover . |
BACKUP | Если таблица данных была изменена в течение ремонта, сохраняет копию файла данных `table_name.MYD' под именем `table_name-datetime.BAK'. |
FORCE | Выполнить ремонт, даже если будет потеряно более, чем одна строка из файла .MYD. |
QUICK | Не проверять строки в таблице, если в ней нет удаленных блоков. |
BACKUP,FORCE
. Это
вынудит провести ремонт таблицы, даже если некоторые строки будут удалены, но
это сохранит старый файл данных как копию так, чтобы Вы могли позже
исследовать то, что с ним случилось.
--pid-file=path
safe_mysqld
.
-P, --port=...
-o, --old-protocol
--one-thread
-O, --set-variable var=option
--help
. Вы можете найти полное описание всех
переменных в разделе "SHOW VARIABLES
".
--safe-mode
--skip-delay-key-write
.
--safe-show-database
--safe-user-create
INSERT
на таблице
mysql.user
или любом столбце в этой таблице.
--skip-concurrent-insert
MyISAM
. Это должно использоваться только, если Вы
думаете, что Вы нашли ошибку в этом свойстве.
--skip-delay-key-write
delay_key_write
для всех таблиц.
--skip-grant-tables
mysqladmin flush-privileges
или
mysqladmin reload
.
--skip-host-cache
--skip-locking
isamchk
или myisamchk
, Вы должны завершить сервер.
Обратите внимание, что в MySQL версии 3.23 Вы можете использовать команды
REPAIR
и CHECK
для ремонта и проверки новых таблиц
системы MyISAM
.
--skip-name-resolve
Host
в
таблицах должны иметь значение IP-адреса или localhost
.
--skip-networking
mysqld
должно быть сделано через сокеты Unix. Эта опция очень
рекомендуется на системах, где позволяются только локальные запросы.
--skip-new
--skip-delay-key-write
. Это также
установит заданный по умолчанию тип таблицы в ISAM
.
--skip-symlink
--skip-safemalloc
--with-debug=full
, все
программы проверят на перекрытие память для каждого распределения и
освобождения памяти. Поскольку эта проверка очень медленная, Вы можете
отказаться от нее, когда Вы не нуждаетесь в постоянной проверке памяти,
используя эту опцию.
--skip-show-database
--skip-stack-trace
mysqld
под программой-отладчиком.
--skip-thread-priority
--socket=path
/tmp/mysql.sock
.
--sql-mode=option[,option[,option...]]
REAL_AS_FLOAT
,
PIPES_AS_CONCAT
, ANSI_QUOTES
,
IGNORE_SPACE
, SERIALIZE
,
ONLY_FULL_GROUP_BY
. Это может также быть пусто
(""
), если Вы хотите сбросить эту настройку. Определяя все
приведенные выше параметры, Вы достигнете того же эффекта, что и опцией
--ansi. Но данной опцией можно включить только необходимые SQL-режимы.
transaction-isolation={READ-UNCOMMITTED|READ-COMMITTED|REPEATABLE-READ|SERIALIZABLE}
-t, --tmpdir=path
/tmp
проживает на разделе слишком маленьком, чтобы
хранить временные таблицы.
-u, --user=user_name
mysqld
как пользователь user_name
.
Эта опция обязательна при запуске mysqld
как root.
-V, --version
-W, --warnings
Aborted connection...
в
файл .err
.MySQL может, начиная с версии 3.22, читать заданные по умолчанию параметры запуска для клиентов и сервера из файлов опций.
MySQL читает заданные по умолчанию параметры из следующих файлов (в Unix):
Имя файла | Зачем он нужен |
/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
не имеет никакого эффекта в то время, когда сервер
ищет файлы опций потому, что он их ищет прежде, чем обрабатывает любые
параметры командной строки.
MySQL читает заданные по умолчанию параметры из следующих файлов (только в ОС Windows):
Имя файла | Зачем он нужен |
windows-system-directory\my.ini | Глобальные опции |
C:\my.cnf | Глобальные опции |
C:\mysql\data\my.cnf | Опции для сервера |
Обратите внимание, что в Windows Вы должны определить все пути с
/
вместо \
. Если Вы используете \
, Вы
должны определить это дважды, поскольку \
символ ESC в MySQL.
MySQL пробует читать файлы опции в порядке, перечисленном выше. Если есть несколько файлов настроек, используется опция, определенная в том файле, который читается позже. Параметры, определенные в командной строке имеют приоритет над параметрами, определенными в любом файле опций. Некоторые параметры могут быть определены, используя системные переменные. Параметры, определенные в командной строке или в файлах опций имеют приоритет над значением соответствующей системной переменной.
Следующие программы поддерживают файлы опций: mysql
,
mysqladmin
, mysqld
, mysqldump
,
mysqlimport
, mysql.server
, myisamchk
и
myisampack
.
Вы можете использовать файлы опций, чтобы определить любую длинную опцию,
которую программа поддерживает! Выполните программу с параметром
--help
, чтобы получить список доступных параметров.
Файл опций может содержать строки следующих форм:
#comment
[group]
group
представляет собой имя программы или группы, для
которой Вы хотите устанавливать параметры. После строки группы любая строка
option
или set-variable
обращается к именованной
группе, пока не будет достигнут конец файла опций или другая строка группы.
option
--option
в командной строке.
option=value
--option=value
в командной строке.
set-variable = variable=value
--set-variable variable=value
в командной
строке. Этот синтаксис должен использоваться, чтобы установить переменную
mysqld
.Группа 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] # The following password will be sent to all standard MySQL clients 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
.
В скриптах оболочки Вы можете использовать команду my_print_defaults, чтобы анализировать файлы конфигурации:
shell> my_print_defaults client mysql --port=3306 --socket=/tmp/mysql.sock --no-auto-rehash
Вышеупомянутый вывод содержит все параметры для групп 'client' и 'mysql'.
В некоторых случаях Вы можете хотеть иметь много различных серверов
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
. Подробности в разделе
"Приложение 2. Переменные окружения
".
Если Вы должны делать это более постоянно, Вы должны создать файл опций для каждого сервера. Подробности в разделе "4.1.2 Файлы опций my.cnf". В Вашем скрипте запуска, который будет выполнен при начальной загрузке (mysql.server?), Вы должны определить для обоих серверов:
safe_mysqld --default-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
Если Вы хотите получить большую эффективность, Вы можете также определять:
tmpdir=path
bdb-tmpdir=path
Если Вы устанавливаете двоичные версии MySQL (файлы .tar) и запускаете их
с ./bin/safe_mysqld
, то обычно придется менять только опции
socket
и port
в скрипте safe_mysqld
.
Имеются обстоятельства, когда Вы могли бы хотеть выполнять много серверов на одной и той же машине. Например, Вы могли бы проверять новый выпуск MySQL при оставлении Вашей существующей безмятежной установки в рабочем состоянии.
Если Вы хотите выполнять много серверов, самый простой путь состоит в том, чтобы компилировать их с различными портами TCP/IP и файлами сокетов так, что они оба не слушают тот же самый порт TCP/IP или файл сокета.
Предположим, что существующий сервер конфигурирован для заданного по
умолчанию номера порта и файла сокета. Теперь конфигурируйте новый сервер
командой выбора конфигурации 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, работающий на уже занятом порте, Вы получите список из наиболее важных переменных настройки в 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
) на различных машинах и разрешение им обращаться
в один каталог данных через NFS
вообще ПЛОХАЯ
ИДЕЯ! Проблема состоит в том, что NFS
станет узким
местом с низким быстродействием. Этот сервис не предполагается для такого
использования. К тому же Вам придется придумывать решение, как надежно
удостовериться, что два или больше процессов mysqld
не
сталкиваются друг с другом. В настоящее время не имеется никакой платформы,
которая была бы 100% надежной, чтобы делать блокировку файла (обычно
lockd
daemon) в любой ситуации. Все же имелся бы еще один
возможный риск с NFS
: этот сервис сделал бы работу для
lockd
еще более сложной. Так что забудьте о таких развлечениях!
Рабочее решение состоит в том, чтобы иметь один компьютер с операционной
системой, которая эффективно обрабатывает потоки, и иметь в нем несколько
CPU и памяти побольше.
Когда Вы хотите соединиться с сервером MySQL, который работает с другим портом, чем порт, который компилируется в Вашего клиента, Вы можете использовать один из следующих методов:
--host 'hostname'
--port=port_number
, чтобы связаться по TCP/IP, или с опцией
[--host localhost] --socket=file_name
для связи через Unix-сокет.
DBD::mysql
, Вы можете читать
все параметры прямо из файлов опций MySQL.
$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.
За последнее время MySQL сильно продвинулась вперед. Уже сейчас эта СУБД стала фактическим стандартом для интернет-приложений (веб-магазины, сложные сайты, информационные порталы). Под открытыми системами (Linux, FreeBSD) и даже под закрытыми, где нет продукции Microsoft (Sun Solaris, разные коммерческие версии Unix), эта СУБД лидирует уже сейчас. Да оно и понятно: она обладает очень высоким быстродействием и надежностью (по некоторым параметрам поспорит даже с известным монстром от Oracle!).
Сейчас в крупных организациях все больше разворачивается война с пиратскими копиями программ. По крайней мере с практикой создания базы данных масштаба предприятия на основе ворованной СУБД явно стараются покончить. MySQL бесплатна (правда, за поддержку надо платить, но ведь поддержка не всем нужна), что еще больше повышает к ней интерес. К тому же, открытые системы ведут сейчас наступление широким фронтом, никуда тут не денешься, а под ними эта СУБД является безусловным лидером, оставив далеко позади все проекты свободных СУБД. Какой смысл покупать и ставить MS SQL под эмулятором в Linux, когда там уже и так есть своя СУБД, мало в чем уступающая MS SQL? Следует также отметить бурный рост числа баз данных масштаба предприятия, который уже начался.
Тут и возникает серьезная проблема: в России с литературой по открытым системам дело обстоит из рук вон плохо. То есть, хуже некуда. Представим такую ситуацию: на предприятии успешно идет внедрение корпоративной БД под MySQL (возможности этой СУБД легко позволяют управиться с потребностями даже довольно крупной компании, проверено лично). Есть много администраторов, которые прекрасно знают язык запросов SQL, имели дело с пакетами, например, от Microsoft или Oracle, но впервые видят MySQL. С другой стороны, они знают, что пакет это хороший, и с ним стоит работать. Понятно, что необходимы знания о том, как это делается, особенно если учесть, что диалект языка SQL, реализованный в MySQL, имеет немало отличий от версии ANSI SQL93.
Вообще документация по MySQL на рынке есть, но направлена она несколько не в ту сторону, куда надо бы. Есть огромные тома (свыше 800 страниц), которые пытаются в одной книге описать все аспекты СУБД, что все равно невозможно сделать качественно ввиду огромных объемов информации. Есть компактные книжки, ориентированные на программистов (да и то тематика этих книг вызывает много вопрсов), но нет почти ничего для администраторов. А ведь администрирование любой СУБД представляет собой далеко не тривиальную задачу. Именно по этой причине и возникла в свое время надобность написать книжку для администратора.
Почему-то молча считается, что эта СУБД нужна даже не администраторам, а программистам. Это далеко не так! Но это убеждение сильно мешает нормальной работе с этой системой.
Нельзя не учесть и то, что любая база данных работает значительно лучше при оптимальной обработке запросов. Разумеется, чтобы запрос обрабатывался оптимально, он должен быть правильно составлен. В этой книге я даю специальную главу по оптимизации запросов, что позволяет повысить эффективность работы пакета примерно в 3-5 раз. Если в предыдущей моей работе (MySQL: руководство пользователя) эта глава была дана в облегченной версии, не затрагивающей оптимальные настройки сервера, то здесь приведена ее полная версия.
Еще одним важным моментом является адаптация пакета к нуждам конкретного проекта. А проблемы тут бывают порой самые неожиданные, вплоть до необходимости дописать к пакету несколько своих функций. В данной работе есть специальная глава, которая дает обзор техники расширения пакета и подгонки его под свои нужды.
Предполагаемый круг читателей: различные администраторы и операторы, использующие в своей работе клиентскую и серверную части данной СУБД, и нуждающиеся в руководстве по практическому (без лишних теорий) использованию пакета. Книга расчитана на подготовленных читателей, имеющих общее представление о базах данных и языке запросов SQL. Крайне желательно также знание его специфического диалекта, примененного в MySQL, впрочем, все особенности я поясняю по ходу изложения. Главы по оптимизации запросов и администрированию пакета могут также весьма пригодиться студентам, изучающим предмет "Базы данных" и программистам, которым приходится писать приложения для взаимодействия с данной СУБД.
Книга представляет практическую ценность для очень широкого круга читателей, особенно для тех, кто стремится сам повысить свой профессиональный уровень. В этой книге рассмотрены следующие вопросы:
Это справочное описание, оно не обеспечивает основные инструкции по SQL или концепциям баз данных, да и не должно это делать. Если Вы хотите получить общую информацию относительно SQL, обратитесь к заключению, там есть ссылки по этим вопросам.
В заключение хочу поблагодарить всех, кто помогал мне в работе над книгой, а особенно:
Вот и подошел к концу обзор базовых средств администрирования и установки пакета СУБД MySQL. Конечно, данная работа не покрывает все вопросы, связанные с работой пакета MySQL. Это, пожалуй, вообще невозможно: слишком уж многообразны вопросы, очень много существует интересных и сложных тем для обсуждения. Поэтому в конце приведен список рекомендованных сайтов, где можно получить дополнительную информацию и советы по возникшей проблеме.
Автор выражает надежду, что эта книга не является последней, и послужит для читателя лишь очередным шагом в изучении сложного и интересного мира под названием "СУБД MySQL".
Тема работы с СУБД MySQL очень сложна и обширна. Охватить все в одной книге едва ли возможно, и я сейчас это понимаю куда лучше, чем перед написанием данной работы.
В этой книге ставилась задача охватить лишь сведения об администрировании пакета, его компиляции, портировании, установке и первоначальной настройке, но сделать это на таком уровне, чтобы рядовой системный администратор пакета не только научился что-то делать, но и хорошо понимал, что и зачем он делает. Эта книга изначально задумывалась как противовес некоторым современным руководствам системы "шаг в сторону считается побегом", которые лишь дают конкретные решения очень узких проблем, совершенно не объясняя сути всех этих решений.
В книге есть решения ряда наболее часто встречающихся проблем с пакетом. Я подробно рассмотрел такие вопросы, как администрирование пакета, резервирование, восстановление и ремонт таблиц, разные типы таблиц и их оптимальное использование в зависимости от ситуации, управление пользователями, систему безопасности и привилегий, локализацию пакета, протоколирование, репликацию, отладку и перенос пакета на другие платформы, кратко рассмотрел расширение пакета.
Кроме того, я включил в книгу полную версию раздела по оптимизации запросов и тестированию пакета. Известно, что любая СУБД работает гораздо лучше, когда ее запросы и формы данных наиболее оптимальны. В данной работе я привожу конкретные рекомендации по этому вопросу, а также объясняю методику тестирования и сравнения реализаций СУБД.
Эта книга не для новичков. Я сразу предполагаю знание читателем хотя бы языка SQL, а лучше его специфической версии MySQL. Изложение самого языка и основ пакета занимает книгу, сопоставимую по размерам с той, что Вы держите в руках. Поэтому она (MySQL: руководство пользователя) выпущена отдельным изданием. Рекомендую Вам ее найти и изучить. В данной работе нет почти ничего интересного по разработке прикладных программ (приложений) с использованием пакета MySQL, кроме краткого описания возможностей по расширению пакета с помощью написания собственных функций.
Надеюсь, что эта тема будет изложена мной в следующих работах из этой серии. Здесь также нет описания многочисленных добавочных программ-расширений для пакета, которых уже написано очень много. Их многообразие и всесторонняя направленность не позволяют охватить их в данной работе, так что я планирую посвятить этим безусловно полезнейшим вспомогательным средствам отдельную книгу.
К сожалению, не могу порекомендовать никакой литературы на русском языке по данному направлению: литература-то есть, хоть ее и мало, но она ориентирована на совсем иной уровень подготовки читателя и другие решаемые задачи. Зато имеется огромное количество ресурсов Internet по MySQL. Большая их часть представлена только на английском языке, однако, там все же можно найти много ценного.
Очень хорошую подборку книг по MySQL, разделенную по темам, можно найти на http://www.mysql.com/portal/books/html/index.html. Сразу предупреждаю, что на русском языке в сети есть только одна работа (написана автором этой книги): http://www.botik.ru/~rldp/articles/mysqlrus/mysqlrus.htm. Она есть и на множестве зеркал в сети, так что Вы ее без труда найдете. Вся прочая информация доступна, главным образом, на английском языке.
Учебники могут быть найдены на: http://www.mysql.com/portal/development/html/development-61-1.html
Много ссылок есть на сайте разработчиков MySQL: http://www.mysql.com/portal/development/html/index.html
Кроме следующих ссылок Вы можете найти и скачать много программ MySQL, инструментальных средств и API из каталога Contrib.
Учебники и руководства по MySQL
mSQL
.
mSQL
Tcl.
DBI
/DBD
.
DBI
/DBD
.
Этот раздел представляет списки рассылки по MySQL и дает некоторые руководящие принципы относительно того, как использовать их.
Чтобы подписаться на главный список рассылки MySQL, пошлите сообщение на mysql-subscribe@lists.mysql.com.
Чтобы отписаться от главного списка рассылки MySQL, пошлите сообщение на mysql-unsubscribe@lists.mysql.com.
Только адрес, с которого Вы посылаете Ваши сообщения, важен. Тема и тело письма не рассматриваются.
Если Ваш адрес ответа неправилен, Вы можете определять ваш адрес явно.
Добавление дефиса к слову subscribe или unsubscribe, сопровождаемое Вашим
адресом, произведет нужный эффект. Замените в адресе символ @
на =. Например, чтобы подписать
your_name@host.domain
, направьте письмо на адрес
mysql-subscribe-your_name=host.domain@lists.mysql.com
.
Почта на адреса mysql-subscribe@lists.mysql.com и mysql-unsubscribe@lists.mysql.com автоматически обрабатывается процессором списка адресатов ezmlm. Информация относительно ezmlm доступна на Web-сайте пакета ezmlm http://www.ezmlm.org .
Чтобы регистрировать сообщение в списке, пошлите его на адрес
mysql@lists.mysql.com
. Однако, пожалуйста, не шлите
туда просьбы о подписке или отписке: список их размножит тысячам читателей.
Если на Вашей локальной машине есть несколько подписчиков рассылки
lists.mysql.com
, стоит подумать о создании своего локального
списка рассылки, чтобы письма с lists.mysql.com
приходили на
Вашу систему в одном экземпляре.
Если Вы хотите отфильтровать сообщения из списка в отдельный почтовый ящик
или еще куда-то, поставьте фильтр, реагирующий на поля List-ID:
или Delivered-To:
в заголовках сообщений рассылки.
Есть следующие списки рассылки:
announce-subscribe@lists.mysql.com announce
mysql-subscribe@lists.mysql.com mysql
mysql-digest-subscribe@lists.mysql.com mysql-digest
mysql
. Это означает, что Вы
получаете все индивидуальные сообщения, посланные как одно большое сообщение
почты один раз в день.
bugs-subscribe@lists.mysql.com bugs
mysqlbug
(если Вы работаете под Windows, Вы
должны включить описание операционной системы и версии MySQL).
Предпочтительно, чтобы Вы проверили проблему при использовании последней
версии пакета. Любой должен быть способен повторить ошибку, используя только
mysql test < script
на присланном образце. Все ошибки,
зарегистрированные в этом списке, будут исправлены или зарегистрированы в
следующем выпуске MySQL. Если имеются только маленькие изменения кода, авторы
также публикуют здесь заплатку, которая решает проблему.
bugs-digest-subscribe@lists.mysql.com bugs-digest
bugs
в виде дайджеста.
internals-subscribe@lists.mysql.com internals
internals-digest-subscribe@lists.mysql.com internals-digest
internals
.
java-subscribe@lists.mysql.com java
java-digest-subscribe@lists.mysql.com java-digest
java
.
win32-subscribe@lists.mysql.com win32
win32-digest-subscribe@lists.mysql.com win32-digest
win32
.
myodbc-subscribe@lists.mysql.com myodbc
myodbc-digest-subscribe@lists.mysql.com myodbc-digest
myodbc
.
plusplus-subscribe@lists.mysql.com plusplus
plusplus-digest-subscribe@lists.mysql.com plusplus-digest
plusplus
.
msql-mysql-modules-subscribe@lists.mysql.com msql-mysql-modules
msql-mysql-modules-digest-subscribe@lists.mysql.com
msql-mysql-modules-digest
msql-mysql-modules
.Подписка на любой список рассылки (как и отписка от него) рассмотрены
выше. Например, чтобы подписаться на список myodbc
(или
отписаться от него), просто пошлите любое сообщение на адрес
myodbc-subscribe@lists.mysql.com или на адрес
myodbc-unsubscribe@lists.mysql.com.
Следующая таблица показывает некоторые рассылки по MySQL не на английском языке. Обратите внимание, что они не эксплуатируются MySQL AB, так что мы не можем гарантировать их качество.
mysql-france-subscribe@yahoogroups.com
list@tinc.net
subscribe mysql your@email.address
,
чтобы подписаться.
mysql-de-request@lists.4t2.com
subscribe mysql-de
your@email.address
, чтобы подписаться. Вы можете найти информацию
относительно этого списка на
http://www.4t2.com/mysql.
mysql-br-request@listas.linkway.com.br
subscribe mysql-br
your@email.address
, чтобы подписаться.
mysql-alta@elistas.net
subscribe mysql
your@email.address
, чтобы подписаться.MySQL очень быстрый, многопоточный, многопользовательский и поддерживающий SQL (Structured Query Language) сервер баз данных.
MySQL является free software. Он лицензируется по GNU GENERAL PUBLIC LICENSE http://www.gnu.org.
Сайт MySQL предоставляет последнюю информацию касательно MySQL.
Следующий перечень описывает наиболее интересные места руководства:
ВАЖНО:
Сообщения об ошибках также как вопросы и комментарии, должны быть посланы
списку рассылки
mysql@lists.mysql.com. Подробности в разделе
"1.4.1 Как сообщать о проблемах и сбоях".
Скрипт mysqlbug
должен использоваться, чтобы генерировать отчеты
об ошибках. Для дистрибутивов исходных текстов скрипт mysqlbug
может быть найден в каталоге scripts. Для двоичных дистрибутивов
mysqlbug
находится в каталоге bin. Если Вы нашли ошибку
защиты в MySQL, Вы должны послать e-mail на
security@mysql.com.
Если Вы имеете любые предложения относительно добавлений или исправлений этого руководства, пожалуйста, пошлите их на docs@mysql.com.
MySQL представляет собой очень популярную систему управления базами данных с открытыми исходными текстами, разрабатываемую MySQL AB. MySQL AB является коммерческой компанией, строящей свой бизнес на сервисах, сосредоточенных на базе данных MySQL. Подробности в разделе "1.1.2 Что такое MySQL AB".
Официально MySQL произносится как "Май-Эс-Ку-Эль", а не как MY-SEQUEL.
MySQL AB является шведской компанией, которая владеет правами на исходные тексты сервера и марку MySQL. Она занимается разработкой, распространением и поддержкой пакета MySQL.
Авторы ищут партнеров, которые хотели бы поддерживать разработку MySQL так, чтобы они могли бы ускорить темп разработки. Если Вы заинтересованы в этом, напишите на e-mail partner@mysql.com!
MySQL AB имеет в настоящее время свыше 20 разработчиков ( http://www.mysql.com/development/team.html) в платежной ведомости, и это число возрастает быстро.
Основные источники дохода:
Авторы пакета хотят, чтобы MySQL всегда был:
MySQL AB и команда MySQL AB:
Началось все с попыток добавить к mSQL
драйвер низкого уровня
для связи с только что разработанным форматом таблиц (ISAM). Однако, после
вдумчивого тестирования, было установлено, что mSQL
недостаточно
быстр и гибок для этого дела. Это закончилось созданием нового интерфейса SQL
к нашей базе данных, но почти с тем же самым интерфейсом API, что и у
mSQL
. Этот API был выбран, чтобы облегчить перенос кодов для
других разработчиков программ.
Название возникло из сокращения (а вернее, слияния) слов My SQL, что на английском языке значит "мой SQL". Названию около десяти лет, оно прижилось еще в те времена, когда пакет не был коммерческой разработкой.
Следующий перечень описывает наиболее важные возможности MySQL:
FLOAT
, DOUBLE
, CHAR
,
VARCHAR
, TEXT
, BLOB
,
DATE
, TIME
, DATETIME
,
TIMESTAMP
, YEAR
,
SET
и ENUM
.
SELECT
и WHERE
. Например:
mysql> SELECT CONCAT(first_name, " ", last_name) FROM tbl_name WHERE income/dependents > 10000 AND age > 30;
GROUP BY
и ORDER
BY
. Поддержка групповых функций (COUNT()
,
COUNT(DISTINCT ...)
, AVG()
, STD()
,
SUM()
, MAX()
и MIN()
).
LEFT OUTER JOIN
и RIGHT OUTER JOIN
с
синтаксисами ANSI SQL и ODBC.
CHAR
или VARCHAR
.
INSERT
, чтобы вставить подмножество столбцов таблицы. Те
столбцы, которым явно не заданы значения, будут автоматически установлены к
их значениям по умолчанию.
myisamchk
, очень быстрая утилита для проверки таблицы,
оптимизации и ремонта. Все функциональные возможности myisamchk
также доступны через интерфейс SQL.
DELETE
, INSERT
, REPLACE
и
UPDATE
возвращают число строк, которые были изменены
(обработаны). Можно взамен вернуть число согласованных строк, устанавливая
флажок при соединении с сервером.
ABS
представляет собой имеющее силу имя столбца. Единственное
ограничение: для обращения к функции никакие пробелы не позволяются между
именем функции и символом скобки (`('), который следует за ним.
--help
или -?
для выдачи справки о параметрах
запуска конкретной программы.
SHOW
может использоваться, чтобы
получить информацию относительно баз данных, таблиц и индексов. Команда
EXPLAIN
может использоваться, чтобы определить, как именно
оптимизатор решает запрос.Этот раздел сводится к вопросам о том, насколько можно доверять пакету, и сколько шансов, что он разнесет на кусочки важный проект, зависящий от него. Строго говоря, MySQL очень надежен.
Попробую разъяснить некоторые проблемы и ответить на некоторые из наиболее важных вопросов, которые, кажется, касаются многих. Этот раздел был собран из информации, собранной из списка рассылки (который является очень активным по части сообщений об ошибках и сбоях).
В TcX MySQL работал без любых проблем в проектах, начиная с середины 1996. Когда MySQL был выпущен на публику, авторы отметили, что имелись некоторые части непроверенного кода, которые были быстро найдены новыми пользователями, делавшими запросы иными способами, чем авторы. Каждый новый выпуск имел меньшее количество проблем мобильности, чем предыдущий (даже при том, что каждый имел много новых свойств).
Каждый выпуск MySQL был пригоден для использования, и имелись проблемы только, когда пользователи начинали использовать код из серых зон. Естественно, пользователи снаружи не видят то, чем являются серые зоны, этот раздел пытается указать, которые зоны в настоящее время известны. Описания имеют дело с MySQL Version 3.23. Все известные и сообщенные ошибки выправлены в последней версии, за исключением ошибок, перечисленных в отдельном разделе, которые являются проблемами, связанными с проектом. Подробности в разделе "1.2.7 Известные ошибки и проблемы".
MySQL написан на нескольких уровнях и различных независимых модулях. Эти модули перечислены ниже с индикацией относительно того, как хорошо проверен каждый из них (сравните с MS SQL Server!):
mysql
, mysqladmin
,
mysqlshow
, mysqldump
и mysqlimport
.
fcntl()
). В
этих случаях Вы должны выполнить MySQL с опцией --skip-locking
.
Проблемы, как известно, происходят на некоторых Linux-системах и на SunOS при
использовании файловых систем по NFS.
fcntl()
,
которое исправлено, используя опцию --skip-locking
для
mysqld
. Некоторые пользователи сообщали о проблемах тупика в
Version 0.5. LinuxThreads должен быть перетранслирован, если Вы планируете
использовать свыше 1000 параллельных подключений. Хотя можно выполнить много
подключений с LinuxThreads по умолчанию (однако, Вы никогда не будете иметь
более, чем 1021 подключение), заданный по умолчанию лимит стека в 2 МБ делает
прикладную программу ненадежной, и она способна свалиться в дамп ядра после
создания 1021 неактивных подключений.
SELECT
обычно выполняются в одном пакете.
LOAD DATA...
, INSERT...SELECT
:
стабильно.
ALTER TABLE
: стабильно.
mysqlaccess
: стабильно.
GRANT
: стабильно.
MySQL
. Они работают хорошо и
могут использоваться после начального тестирования.
MERGE
все еще не
оттестировано как следует. Другая часть кода MERGE
проверена.
MySQL AB обеспечивает поддержку по электронной почте для покупателей соответствующей услуги, но список рассылки MySQL обычно обеспечивает ответы на общие вопросы. Ошибки обычно исправляются сразу же с помощью патча, для серьезных ошибок почти всегда имеется новый выпуск.
MySQL Version 3.22 имеет лимит в 4G на размер таблицы. С новым кодом
MyISAM
в MySQL Version 3.23 максимальный размер таблицы увеличен
до 8 миллионов терабайт (2^63 байт).
Обратите внимание, однако, что операционные системы имеют их собственные ограничения размера файла. Имеются некоторые примеры:
Операционная система | Ограничение размера файла |
Linux-Intel 32 bit | 2G, 4G или больше, зависит от версии Linux |
Linux-Alpha | 8T (?) |
Solaris 2.5.1 | 2G (возможно, до 4G с патчем) |
Solaris 2.6 | 4G |
Solaris 2.7 Intel | 4G |
Solaris 2.7 ULTRA-SPARC | 8T (?) |
В Linux 2.2 Вы можете получать таблицы больше, чем 2G, используя заплату LFS для файловой системы ext2. В Linux 2.4 существует также заплата для ReiserFS, чтобы получить поддержку для больших файлов.
Это означает, что размер таблицы для MySQL обычно ограничивается операционной системой, а не самим пакетом.
По умолчанию таблицы MySQL имеют максимальный размер около 4G. Вы можете
проверять максимальный размер таблицы для каждой конкретной таблицы с помощью
команды SHOW TABLE STATUS
или утилитой myisamchk -dv
table_name
. Подробности приведены в
разделе "4.5.5 Синтаксис SHOW
".
Если Вы нуждаетесь в таблицах, больших, чем 4G (и Ваша операционная
система поддерживает это), Вы должны установить параметры
AVG_ROW_LENGTH
и MAX_ROWS
, когда Вы создаете Вашу
таблицу. Вы можете установить их и позже с помощью ALTER TABLE
.
Если Ваша большая таблица нужна только для чтения, Вы могли бы
использовать myisampack
, чтобы объединить и сжать много таблиц в
одну. Утилита myisampack
обычно сжимает таблицу по крайней мере
на 50%, так что Вы можете иметь намного большие таблицы.
Вы можете обойти ограничения размера файла операционной системы для
файлов данных MyISAM
, используя опцию RAID
.
Другое решение может быть реализовано с помощью библиотеки MERGE, которая позволяет Вам обрабатывать совокупность идентичных таблиц как одну.
MySQL непосредственно не имеет никаких трудностей с проблемой 2000 (Y2K):
2069
. Все годы с 2 цифрами расценены в интервале от
1970
до 2069
, это означает, что, если Вы сохраняете
01
в столбце типа year
, MySQL обрабатывает это как
2001
.
YEAR
может
сохранять годы 0
и в интервале от 1901
до
2155
в 1 байте, а также отображать их, используя 2 или 4 цифры.
Вы можете сталкиваться с проблемами в прикладных программах, которые
используют MySQL, но сами несовместимы с проблемой Y2K. Например, много
старых прикладных программ сохраняют или управляют значениями лет,
используя числа с 2 цифрами (которые являются неоднозначными). Эта проблема
также может быть составлена прикладными программами, которые используют
00
или 99
как значения для индикатора "пропустить".
В свое время пришлось столкнуться с программой, которая помечала удаленные
записи, выставляя им год 00
...
К сожалению, эти проблемы могут быть трудными в исправлении потому, что различные прикладные программы могут быть написаны различными программистами, каждый из которых может использовать различный набор соглашений и обрабатывающих даты функций.
Имеется простой пример, иллюстрирующий, что MySQL не имеет любых проблем с датами до года 2030:
mysql> DROP TABLE IF EXISTS y2k; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE y2k (date date, date_time datetime, time_stamp timestamp); Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO y2k VALUES -> ("1998-12-31","1998-12-31 23:59:59",19981231235959), -> ("1999-01-01","1999-01-01 00:00:00",19990101000000), -> ("1999-09-09","1999-09-09 23:59:59",19990909235959), -> ("2000-01-01","2000-01-01 00:00:00",20000101000000), -> ("2000-02-28","2000-02-28 00:00:00",20000228000000), -> ("2000-02-29","2000-02-29 00:00:00",20000229000000), -> ("2000-03-01","2000-03-01 00:00:00",20000301000000), -> ("2000-12-31","2000-12-31 23:59:59",20001231235959), -> ("2001-01-01","2001-01-01 00:00:00",20010101000000), -> ("2004-12-31","2004-12-31 23:59:59",20041231235959), -> ("2005-01-01","2005-01-01 00:00:00",20050101000000), -> ("2030-01-01","2030-01-01 00:00:00",20300101000000), -> ("2050-01-01","2050-01-01 00:00:00",20500101000000); Query OK, 13 rows affected (0.01 sec) Records: 13 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM y2k; +------------+---------------------+----------------+ | date | date_time | time_stamp | +------------+---------------------+----------------+ | 1998-12-31 | 1998-12-31 23:59:59 | 19981231235959 | | 1999-01-01 | 1999-01-01 00:00:00 | 19990101000000 | | 1999-09-09 | 1999-09-09 23:59:59 | 19990909235959 | | 2000-01-01 | 2000-01-01 00:00:00 | 20000101000000 | | 2000-02-28 | 2000-02-28 00:00:00 | 20000228000000 | | 2000-02-29 | 2000-02-29 00:00:00 | 20000229000000 | | 2000-03-01 | 2000-03-01 00:00:00 | 20000301000000 | | 2000-12-31 | 2000-12-31 23:59:59 | 20001231235959 | | 2001-01-01 | 2001-01-01 00:00:00 | 20010101000000 | | 2004-12-31 | 2004-12-31 23:59:59 | 20041231235959 | | 2005-01-01 | 2005-01-01 00:00:00 | 20050101000000 | | 2030-01-01 | 2030-01-01 00:00:00 | 20300101000000 | | 2050-01-01 | 2050-01-01 00:00:00 | 00000000000000 | +------------+---------------------+----------------+ 13 rows in set (0.00 sec)
Это показывает, что типы DATE
и DATETIME
не
будут давать никаких проблем с будущими датами (они легко обрабатывают даты
вообще до 9999 года).
Тип TIMESTAMP
, который используется, чтобы сохранить текущее
(актуальное) время, имеет диапазон только до 2030-01-01
.
TIMESTAMP
имеет диапазон от 1970
до
2030
на 32-разрядных машинах (значение со знаком). На
64-разрядных машинах это обрабатывает времена до 2106
года
(значение без знака).
Даже при том, что MySQL Y2K-совместим, Вы отвечаете за то, чтобы обеспечить однозначный ввод.
Этот раздел описывает, как MySQL соответствует стандартам ANSI SQL. MySQL имеет много расширений для них, здесь Вы выясните, что они из себя представляют, и как использовать их. Вы также найдете информацию относительно функциональных возможностей, отсутствующих в MySQL, и как обойти проблемы.
MySQL включает некоторые расширения, которые Вы, вероятно, не будете
находить в других базах данных SQL. Предупреждаю, что, если Вы используете
их, Ваш код не будет переносимым на другие SQL-серверы. В некоторых случаях
Вы можете писать код, который включает MySQL-расширения, но все же является
переносимым за счет комментариев формы /*! ... */
. В этом случае
MySQL анализирует и выполнит код внутри комментария, но другие SQL-серверы
игнорируют расширения. Например:
SELECT /*! STRAIGHT_JOIN */ col_name FROM table1,table2 WHERE ...
Если Вы добавляете номер версии после '!'
, синтаксис будет
выполнен только, если версия MySQL равна или больше, чем этот номер версии:
CREATE /*!32302 TEMPORARY */ TABLE (a int);
Это означает, что, если Вы имеете Version 3.23.02 или более новую, MySQL
использует ключевое слово TEMPORARY
.
MySQL-расширения перечислены ниже:
MEDIUMINT
, SET
,
ENUM
и разные типы BLOB
и TEXT
.
AUTO_INCREMENT
, BINARY
,
NULL
, UNSIGNED
и ZEROFILL
.
BINARY
или использовать ключевое слово BINARY
,
которое заставляет сравнения быть выполненными согласно порядку ASCII,
используемому на сервере MySQL.
db_name.tbl_name
. Некоторые
SQL-серверы обеспечивают те же самые функциональные возможности, но называют
это User space
. MySQL не поддерживает пространство таблиц как
in: create table ralph.my_table...IN my_tablespace
.
LIKE
позволяется на числовых столбцах.
INTO OUTFILE
и STRAIGHT_JOIN
допустимо в инструкции SELECT
.
SQL_SMALL_RESULT
в инструкции SELECT
.
EXPLAIN SELECT
, чтобы получить описание
того, как таблицы соединены.
INDEX
или KEY
в инструкции
CREATE TABLE
.
TEMPORARY
или IF NOT EXISTS
с
CREATE TABLE
.
COUNT(DISTINCT list)
, где 'list' включает больше,
чем один элемент.
CHANGE col_name
, DROP col_name
или
DROP INDEX
, IGNORE
или RENAME
в вызове
команды ALTER TABLE
.
RENAME TABLE
.
ADD
, ALTER
,
DROP
или CHANGE
в одном
вызове ALTER TABLE
.
DROP TABLE
с ключевым словом IF EXISTS
.
DROP
TABLE
.
LIMIT
в инструкции DELETE
.
DELAYED
в инструкциях INSERT
и
REPLACE
.
LOW_PRIORITY
в инструкциях INSERT
,
REPLACE
, DELETE
и UPDATE
.
LOAD DATA
INFILE
. Во многих случаях этот синтаксис совместим с Oracle
LOAD DATA INFILE
.
ANALYZE TABLE
, CHECK TABLE
,
OPTIMIZE TABLE
и REPAIR TABLE
.
SHOW
.
SET OPTION
.
GROUP BY
.
Это дает лучшую эффективность для некоторых очень специфических, но
совершенно нормальных запросов.
ASC
и DESC
с вызовом
GROUP BY
. Очень полезно.
||
и &&
в качестве
OR и AND, как в языке программирования C. В MySQL ||
и
OR
синонимы, так же как &&
и AND
.
Из-за этого хорошего синтаксиса MySQL не поддерживает оператор ANSI SQL
||
для конкатенации строк, используйте вместо него
CONCAT()
. Поскольку CONCAT()
берет любое число
параметров, просто преобразовать использование ||
в MySQL.
CREATE DATABASE
или DROP DATABASE
.
%
является синонимом для MOD()
. То есть N%M
равносильно MOD(N,M)
. %
поддержан для
C-программистов и для совместимости с PostgreSQL.
=
, <>
, <=
,
<
, >=
,>
,
<<
, >>
, <=>
,
AND
, OR
или LIKE
могут использоваться
в сравнениях столбца слева от FROM
в инструкции
SELECT
. Например, так:
mysql> SELECT col1=1 AND col2=2 FROM tbl_name;
LAST_INSERT_ID()
.
REGEXP
и
NOT REGEXP
в операторах.
CONCAT()
или CHAR()
с одним
параметром или больше, чем с двумя параметрами. В MySQL эти функции могут
брать любое число параметров.
BIT_COUNT()
, CASE
, ELT()
,
FROM_DAYS()
, FORMAT()
, IF()
,
PASSWORD()
, ENCRYPT()
, md5()
,
ENCODE()
, DECODE()
, PERIOD_ADD()
,
PERIOD_DIFF()
, TO_DAYS()
и WEEKDAY()
.
TRIM()
для подрезания подстрок. ANSI SQL
поддерживает удаление только одиночных символов.
GROUP BY
можно использовать STD()
,
BIT_OR()
и BIT_AND()
.
REPLACE
вместо связки
DELETE
+INSERT
.
FLUSH flush_option
.
:=
:
SELECT @a:=SUM(total),@b=COUNT(*),@a/@b AS avg FROM test_table; SELECT @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
Авторы пробуют заставить MySQL следовать стандартам ANSI SQL и ODBC SQL, но в некоторых случаях MySQL обрабатывает некоторые дела по-другому:
--
является комментарием, только если сопровождается
незаполненным пространством. Подробности чуть ниже.
VARCHAR
конечные пробелы будут удалены, когда
значение сохранено. Подробности в разделе "1.2.7
Известные ошибки и проблемы".
CHAR
тихо меняются на столбцы
типа VARCHAR
.
REVOKE
, чтобы отменить все
привилегии для таблицы.
NULL AND FALSE
вернет NULL
вместо
FALSE
, чтобы не возиться долго с оценкой выражений.Если Вы запустили mysqld
с опцией --ansi
,
поведение MySQL изменится следующим образом:
||
является конкатенацией строк, а не OR
.
REAL
превратится в синоним для FLOAT
вместо
синонима для DOUBLE
.
SERIALIZABLE
.Этого также можно достичь опцией --sql-mode=REAL_AS_FLOAT,
PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,SERIALIZE,ONLY_FULL_GROUP_BY
.
Следующие функциональные возможности отсутствуют в текущей версии MySQL. Есть список, указывающий, когда новые расширения могут быть добавлены к MySQL (с их приоритетами), его можно посмотреть в Интернете по адресу http://www.mysql.com/documentation/manual.php?section=TODO.
MySQL в настоящее время поддерживает sub-selects только в виде
INSERT ... SELECT ...
и REPLACE ... SELECT ...
.
Вы можете, однако, использовать функцию IN()
в других контекстах.
Во многих случаях Вы можете переписать запрос без sub-select:
SELECT * FROM table1 WHERE id IN (SELECT id FROM table2);
Это может быть переделано так:
SELECT table1.* FROM table1,table2 WHERE table1.id=table2.id;
Запросы:
SELECT * FROM table1 WHERE id NOT IN (SELECT id FROM table2); SELECT * FROM table1 WHERE NOT EXISTS (SELECT id FROM table2 where table1.id=table2.id);
Могут быть переделаны так:
SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id where table2.id IS NULL
Для более сложных подзапросов Вы можете часто создавать временные таблицы,
чтобы сохранить подзапрос. В некоторых случаях эта опция не будет работать.
Наиболее часто это происходит с инструкциями DELETE
, для которых
стандарт SQL не поддерживает объединения (за исключением sub-selects). Для
этой ситуации имеются два решения, доступные пока подзапросы не поддержаны.
Первое должно использовать процедурный язык программирования (типа Perl
или PHP) чтобы представить на рассмотрение такой запрос SELECT
,
чтобы получить первичные ключи для записей, которые будут удалены, и затем
использовать эти значения, чтобы создать инструкцию DELETE
(DELETE FROM ... WHERE ... IN (key1, key2, ...)
).
Второе решение должно использовать интерактивный SQL для автопостроения
набора инструкций DELETE
при использовании MySQL-расширения
CONCAT()
(вместо стандартного оператора ||
):
SELECT CONCAT('DELETE FROM tab1 WHERE pkid = ', tab1.pkid, ';') FROM tab1, tab2 WHERE tab1.col1 = tab2.col2;
Вы можете помещать этот запрос в файл скрипта и переназначать ввод на
интерпретатор командных строк mysql
, отправив вывод на его
вторую копию клиента:
prompt> mysql --skip-column-names mydb < myscript.sql|mysql mydb
MySQL 4.0 поддерживает многотабличное удаление, которое может использоваться, чтобы эффективно удалить строки, основанные на информации из одной таблицы (или даже из многих таблиц) в то же самое время.
SELECT INTO TABLE
MySQL не поддерживает Oracle SQL-расширение SELECT ... INTO
TABLE ...
. MySQL вместо него поддерживает синтаксис ANSI SQL
INSERT INTO ... SELECT ...
, который является в основном той
же самой функциональностью.
INSERT INTO tblTemp2 (fldID) SELECT tblTemp1.fldOrder_ID FROM tblTemp1 WHERE tblTemp1.fldOrder_ID > 100;
Альтернативно, Вы можете использовать SELECT INTO OUTFILE...
или CREATE TABLE ... SELECT
, чтобы решить Вашу проблему.
Поскольку MySQL в настоящее время поддерживает транзакции, следующее обсуждение имеет силу, только если Вы используете не транзакционно-безопасные типы таблицы.
Часто спрашивают, почему MySQL не транзационная база данных?
MySQL сделал сознательное решение поддерживать другую парадигму для целостности данных: атомные операции. Дело в том, что атомные операции предлагают равную или даже лучшую целостность с намного лучшей эффективностью. Однако, авторы пакета тем не менее оценивают и понимают транзакционную парадигму базы данных и планируют в следующих версиях представить транзакционно-безопасные таблицы. Пользователям будет предоставлена возможность решить, нуждаются ли они в быстродействии атомных операций, или они должны использовать свойства транзакций в своих программах.
Давайте разберемся в том, как MySQL поддержает строгую целостность, и сравним эти свойства с транзакциями.
Перво-наперво в транзакционной системе, если Ваши программы в критических ситуациях вызывают rollback вместо commit, транзакционная схема удобней. Кроме того, транзакции гарантируют, что незаконченные модификации или разрушительные действия не будут применены к базе данных немедленно, сервер дает возможность сделать автоматическую обратную перемотку, и Ваша база данных будет сохранена.
MySQL почти во всех случаях позволяет Вам обойти проблемы включением простых проверок перед модификациями и запуском простых скриптов, которые проверяют целостность базы данных, а также автоматически проводят ремонт. Обратите внимание, что только используя файл регистрации MySQL или даже добавляя один дополнительный файл регистрации, обычно можно востанавливать таблицы без потери целостности данных.
Кроме того, фатальные модификации в транзакционной схеме могут быть
переделаны так, чтобы стать атомными. Фактически все проблемы целостности,
которые решают транзакции, могут быть выполнены с помощью LOCK
TABLES
или атомными модификациями, гарантируя, что Вы никогда не
получите автоматическое аварийное прекращение работы базы данных, что
является общей проблемой для транзакционных баз данных.
Далеко не все транзакции могут предотвращать потерю данных, если сервер рушится. В таких случаях даже транзакционная система может терять данные. Никакая система не 100%-но безопасна, речь идет лишь о минимизации потерь. Даже Oracle, как сообщают, иногда теряет данные в таких ситуациях, хоть и считается самой безопасной из транзакционных баз данных.
Чтобы обеспечить безопасность в MySQL, Вы должны только иметь копии и регистрацию модификаций. С этим Вы можете восстановить фактически любое повреждение базы данных.
Транзакционная парадигма имеет выгоды и недостатки. Много пользователей и
разработчиков прикладных программ зависят от легкости, с которой они могут
обойти проблемы, где аварийное прекращение работы появляется или необходимо,
и им, вероятно, придется делать немного больше работы с MySQL, чтобы думать
по-другому или писать больше. Если Вы плохо знакомы с атомной парадигмой
операций или более знакомы с транзакциями, не считайте, что MySQL не знаком с
этими проблемами. Надежность и целостность у авторов этого пакета стоят на
первом месте! Недавние оценки указывают, что имеется больше, чем 1000000
серверов mysqld
, многие из которых находятся в промышленных
средах. Очень редко можно услышать от пользователей, что они потеряли данные,
и почти во всех случаях виноваты были сами пользователи. Это самое лучшее
доказательство стабильности и надежности MySQL.
Наконец, в ситуациях, где целостность имеет самую высокую важность,
текущие свойства MySQL учитывают уровень транзакции или лучшую надежность и
целостность. Если Вы блокируете таблицы с помощью LOCK TABLES
,
все модификации остановятся, пока любые проверки целостности не будут
сделаны. Если Вы только получаете блокировку чтения (в противоположность
блокировке записи), то чтение и вставки продолжают работать. Новые
вставленные записи не будут замечены клиентами, имеющими блокировку
READ
, пока они не освободят их блокировки чтения. С помощью
INSERT DELAYED
Вы можете поместить вставки в локальную очередь,
где они останутся до тех пор, пока блокировки не будут освобождены. Таким
образом, сервер не будет иметь пользователя, который ждет завершения вставки.
"Атомная" означает, что Вы можете убедиться в том, что в то время как
каждая специфическая модификация выполняется, никакой другой пользователь не
может сталкиваться с ней, и никакой автоматической обратной перемотки не
будет никогда (хотя это может случаться на транзакционных системах, если Вы
не очень осторожны). MySQL также гарантирует, что не будет иметься лишних
чтений. Вы можете найти пример того, как писать атомные модификации в разделе
"1.2.6 Как справиться без
COMMIT
/ROLLBACK
".
Использование атомной парадигмы позволяет применять много оптимизаций быстродействия, которые иначе не будут возможны. К тому же, при грамотном подходе такая схема ускорит работу в 3-5 раз по сравнению с лучшими транзакционными базами данных при той же надежности.
Для тех случаев, где безопасность более важна, чем быстродействие, я
советую применять транзакционные таблицы типов BDB
или
InnoDB
для всех критических данных.
Одно заключительное примечание: в настоящее время авторы пакета работают над безопасной схемой репликации, которая должна быть лучше, чем любая известная на сегодняшний день поддержка репликации. Эта система будет работать наиболее надежно при атомных операциях, а не транзакциях.
Хранимая процедура представляет собой набор команд SQL, который может компилироваться и храниться на сервере. Как только это было выполнено, клиент не должен хранить весь запрос, а может обратиться к сохраненной процедуре. Это обеспечивает лучшую эффективность потому, что запрос должен анализироваться только однажды, и меньшее количество информации должно быть послано между клиентом и сервером. Вы можете также поднимать концептуальный уровень при наличии библиотек функций.
Триггер представляет собой сохраненную процедуру, которая вызывается, когда специфическое событие происходит. Например, Вы можете устанавливать сохраненную процедуру, которая будет вызвана каждый раз, когда запись удалена из таблицы transaction. Эта процедура автоматически удаляет соответствующего заказчика из таблицы customer, когда все его транзакции удалены.
Запланированный язык модификаций будет способен обработать сохраненные процедуры, но без триггеров. Триггеры обычно замедляют все, даже запросы, к которым не имеют отношения.
Обратите внимание, что внешние ключи в SQL не используются, чтобы
соединить таблицы, но используются обычно для проверки справочной
целостности. Если Вы хотите получить результат из нескольких таблиц командой
SELECT
, Вы делаете это, соединяя таблицы так:
SELECT * from table1,table2 where table1.id = table2.id;
Синтаксис FOREIGN KEY
в MySQL существует только для
совместимости с другими версиями SQL-команды CREATE TABLE
, это
не делает ничего. Синтаксис FOREIGN KEY
без ON DELETE ...
обычно используется для документационных целей. Некоторые прикладные
программы стандарта ODBC могут использовать это, чтобы произвести
автоматические предложения WHERE
, но это обычно просто, чтобы
перекрыть. FOREIGN KEY
иногда используется как проверка
ограничения, но эта проверка практически не нужна, если строки вставлены в
таблицы в правильном порядке. MySQL поддерживает эти предложения только
потому, что некоторые прикладные программы требуют, чтобы они существовали
(независимо от того, работают они или нет).
В MySQL Вы можете обойти проблему неработающей конструкции
ON DELETE ...
добавляя соответствующую инструкцию
DELETE
к прикладной программе, когда Вы удаляете записи из
таблицы, которая имеет внешний ключ. Практически это иногда быстрее и намного
более переносимо, чем использование внешних ключей в таблице.
В ближайшем будущем мы расширим реализацию FOREIGN KEY
так,
чтобы по крайней мере информация была сохранена в файле спецификации таблицы
и могла быть получена mysqldump
и ODBC. На более поздней стадии
мы выполним ограничения внешних ключей для прикладной программы, которая не
может легко быть перекодирована, чтобы избежать их.
Много ученых по теории базы данных и программистов чувствуют, что справочная целостность должна быть предписана внутри сервера базы данных. Действительно, во многих случаях этот подход очень полезен. Однако, в разговоре со многими пользователями баз данных авторы наблюдали, что внешние ключи часто неправильно используются, что может вызывать серьезные проблемы. Даже когда все используется правильно, это не волшебное решение для проблемы справочной целостности, хотя это делает все проще в некоторых случаях.
Из-за вышеупомянутых наблюдений авторы не назначали реализации внешних ключей высокий приоритет. Однако, в последние годы ядро пользователей расширилось, и теперь авторы пакета имеют много пользователей, кто хотел бы иметь предписанную поддержку справочной целостности внутри MySQL. Так что в ближайшем будущем внешние ключи все-таки будут реализованы.
Некоторые преимущества применения внешних ключей:
Противопоказания:
MySQL не поддерживает views, но это планируется исправить примерно к 4.1.
Views обычно полезны для разрешения пользователям обращаться к набору отношений как к одной таблице (в режиме только для чтения). Многие базы данных SQL не позволяют модифицировать любые строки в таком представлении: Вы должны делать все модификации в отдельных таблицах.
MySQL обычно используется в прикладных программах и на web-системах, где автор прикладной программы имеет полное управление над применением базы данных. По этой причине views не сочтены очень важными.
Чтобы ограничить доступ к столбцам в MySQL views тоже не требуются: MySQL имеет очень сложную систему предоставления привилегий. Подробности в разделе "4.2 Общие проблемы защиты и система привилегий доступа MySQL".
Некоторые базы данных SQL применяют -- как начало
комментария. MySQL имеет # как символ начала комментария, даже
если инструмент командной строки mysql
удаляет все строки,
начинающиеся с --. Вы можете также использовать стиль
комментариев языка C (/* это комментарий */
) в MySQL.
MySQL Version 3.23.3 и выше поддерживает стиль комментариев
--, только если комментарий сопровождается пробелом. Это потому,
что стиль комментария вызвал много проблем с автоматически сгенерированными
запросами SQL, которые использовали нечто вроде следующего кода, где мы
автоматически вставляем значение payment вместо !payment!
:
UPDATE tbl_name SET credit=credit-!payment!
Как Вы думаете, что случится, когда значение payment
отрицательное? А вот что. Поскольку 1--1
допустимо в SQL, пакет
думает, что начался комментарий типа --. Вряд ли это
входит в Ваши планы...
В MySQL Version 3.23 Вы можете использовать:
1-- Это был комментарий
Следующее обсуждение касается Вас, только если Вы управляете MySQL Version 3.23 или ранее:
Если Вы имеете программу SQL в текстовом файле, который содержит комментарии --, Вы должны использовать:
shell> replace " --" " #" < text-file-with-funny-comments.sql \ | mysql database
Вместо обычного решения:
shell> mysql database < text-file-with-funny-comments.sql
Вы можете также редактировать командный файл, чтобы сменить комментарии -- на #:
shell> replace " --" " #" -- text-file-with-funny-comments.sql
Замените их обратно этой командой:
shell> replace " #" " --" -- text-file-with-funny-comments.sql
Entry level SQL92. ODBC levels 0-2.
COMMIT
/ROLLBACK
Следующее обычно применяется только для таблиц ISAM
,
MyISAM
и HEAP
. Если Вы используете только
транзакционно-безопасные таблицы (BDB
или InnoDB
) в
модификации, Вы можете также делать
COMMIT
и ROLLBACK
в MySQL.
Проблема с эффективной обработкой
COMMIT
-ROLLBACK
с вышеупомянутыми типами таблиц
требует полностью иного размещения таблицы, чем используемое MySQL сегодня.
Тип таблицы также нуждался бы в дополнительных потоках, которые вели бы
автоматические очистки на таблицах, да и использование дисков было бы намного
выше. Это сделало бы эти типы таблицы приблизительно в 2-4 медленнее, чем
они есть сейчас.
Текущей проблемой является ROLLBACK
. Без
ROLLBACK
Вы можете делать любой вид COMMIT
с
помощью LOCK TABLES
. Для поддержки ROLLBACK
с
вышеупомянутыми типами таблицы MySQL должен быть изменен так, чтобы сохранять
все старые записи, которые модифицировались, и иметь возможность быстро
вернуться к отправной точке, если была выдана команда ROLLBACK
.
Для простых случаев это довольно просто (можно приспособить сюда
isamlog
), но будет намного трудней выполнить
ROLLBACK
для ALTER/DROP/CREATE TABLE
.
Чтобы избежать использования ROLLBACK
, Вы можете использовать
следующую стратегию действий:
LOCK TABLES ...
, чтобы блокировать все
таблицы, к которым Вы хотите обращаться.
UNLOCK TABLES
, чтобы снять блокировки.Это обычно намного более быстрый метод, чем использование транзакций с
возможностью ROLLBACK
, хотя и не всегда. Единственная ситуация,
которую это решение не обрабатывает, состоит в том, что кто-то уничтожает
поток в середине модификации. В этом случае все блокировки будут сняты, но
некоторые из модификаций, возможно, не будут выполнены.
Вы можете также использовать функции, чтобы модифицировать записи в одиночной операции. Вы можете получать очень эффективную прикладную программу, применяя следующие методы:
Например, когда мы делаем модификации некоторой информации заказчика, мы
модифицируем только данные заказчика, которые изменились, и проверяем, что ни
один из измененных данных или других данных, которые зависят от измененных
данных, не изменился по сравнению с первоначальной строкой. Тест для
измененных данных выполнен с предложением WHERE
в инструкции
UPDATE
. Если запись не модифицировалась, мы даем пользователю
сообщение о том, что некоторые из данных, которые Вы изменили, были изменены
другим пользователем. Затем мы показываем старую строку против новой строки в
окне, так что пользователь может решать, которую версию записи заказчика он
должен будет использовать.
Это дает нам нечто, что является подобным блокировке столбца, но
фактически это даже лучше потому, что мы модифицируем только некоторые из
столбцов, используя значения, которые вычислены относительно их текущих
значений. Это означает, что типичные инструкции UPDATE
выглядят
примерно таким образом:
UPDATE tablename SET pay_back=pay_back+'relative change'; UPDATE customer SET customer_date='current_date', address='new address', phone='new phone', money_he_owes_us=money_he_owes_us+'new_money' WHERE customer_id=id AND address='old address' AND phone='old phone';
Как Вы можете видеть, это очень эффективно и работает, даже если другой
пользователь изменил значения столбцов pay_back
или
money_he_owes_us
.
Во многих случаях пользователи
хотели использовать ROLLBACK
и/или LOCK TABLES
с
целью управления уникальными идентификаторами для некоторых таблиц. Это может
быть обработано намного более эффективно, используя столбец
AUTO_INCREMENT
и функцию SQL LAST_INSERT_ID()
или
функцию C API mysql_insert_id()
.
В MySQL AB авторы пакета никогда не имели никакой потребности в блокировке уровня строки потому, что всегда могли ее обойти. Некоторые случаи и в самом деле нуждаются в блокировке строки, но они очень немногочисленны. Если Вы хотите иметь блокировку уровня строки, Вы можете использовать столбец флажка в таблице и делать нечто вроде:
UPDATE tbl_name SET row_flag=1 WHERE id=ID;
MySQL вернет для числа обработанных строк, если строка была найдена, и
row_flag
не был 1 в первоначальной строке.
Перечисленные ниже проблемы известны авторам пакета, и их устранение имеет очень высокий приоритет.
ANALYZE TABLE
на таблицах BDB может в некоторых случаях
делать таблицу непригодной, пока Вы не перезапустите mysqld
.
Когда это выполнено, Вы будете видеть ошибки подобные следующим в файле
регистрации ошибок MySQL:
001207 22:07:56 bdb: log_flush: LSN past current end-of-log
ALTER TABLE
на таблице BDB
, на
которой Вы управляете незавершенными многооператорными транзакциями.
Транзакция будет, вероятно, игнорироваться.
ANALYZE TABLE
, OPTIMIZE TABLE
и REPAIR
TABLE
могут вызывать проблемы на таблицах, для которых Вы используете
вызов INSERT DELAYED
.
LOCK TABLE ...
и FLUSH TABLES ...
еще не гарантирует, что не имеется наполовину выполненной транзакции.
mysql
на этой базе данных, если Вы не используете опцию
-A
или применяете rehash
. Это особенно важно, когда
Вы имеете большой кэш таблицы.
LOAD DATA
INFILE
и выравнивать символы признака конца строки, которые сами
занимают больше, чем 1 символ.Следующие проблемы известны и будут устранены в назначенное время:
MATCH
работает только с инструкциями
SELECT
.
SET CHARACTER SET
не могут быть применены
транслируемые символы в базе данных, таблице и столбцах.
DELETE FROM merge_table
, используемый без
WHERE
, только очистит отображение для таблицы, не удаляя ничего
в самих отображенных таблицах.
BLOB
не могут надежно использоваться в GROUP
BY
, ORDER BY
или DISTINCT
. Только первые
max_sort_length
байт (по умолчанию 1024) используются при
сравнении BLOB
в этих случаях. Это может быть изменено с помощью
опции -O max_sort_length
при запуске mysqld
. Обход
для большинства случаев должен использовать подстроку: SELECT DISTINCT
LEFT(blob,2048) FROM tbl_name
.
BIGINT
или DOUBLE
(оба обычно длиной в 64 бита). Это зависит от функции, которую обрабатывает
пакет. Общее правило: битовые функции выполнены с точностью
BIGINT
, IF
и ELT()
с
BIGINT
или DOUBLE
, а все прочие с
DOUBLE
. Нужно пробовать избегать использовать большие длинные
значения без знака (9223372036854775807)!
BLOB
и TEXT
,
автоматически удаляют все конечные пробелы, когда сохраняются. Для типа
CHAR
это разрешено и может быть расценено как свойство согласно
ANSI SQL92. Ошибка в том, что в MySQL столбцы VARCHAR
обрабатываются тем же самым путем.
ENUM
и
SET
для каждой таблицы.
safe_mysqld
переназначает все сообщения mysqld
в файл регистрации mysqld
. Одна проблема с этим состоит в том,
что, если Вы выполняете mysqladmin refresh
, чтобы закрыть и
вновь открыть файл регистрации, stdout
и stderr
все еще переназначаются к старому файлу регистрации. Если Вы используете
опцию --log
, Вы должны редактировать safe_mysqld
,
чтобы регистрировать данные в файле 'hostname'.err вместо
'hostname'.log, чтобы у Вас не было крупных проблем с запуском и
работой с mysqladmin refresh
.
UPDATE
столбцы модифицируются слева направо.
Если Вы обращаетесь к модифицируемому столбцу, Вы получите модифицируемое
значение вместо первоначального значения. Например:
mysql> UPDATE tbl_name SET KEY=KEY+1,KEY=KEY+1;Это модифицирует
KEY
с 2
вместо 1
.
select * from temporary_table, temporary_table as t2;
RENAME
не работает с таблицами TEMPORARY
.
DISTINCT
по-разному, если Вы
используете скрытые столбцы в объединении или нет. В объединении скрытые
столбцы рассчитаны как часть результата (даже если они не показаны) в то
время, как в нормальном запросе они не участвуют в сравнении
DISTINCT
. Мы, вероятно, изменим это в будущем, чтобы никогда не
сравнить скрытые столбцы при выполнении DISTINCT
. Например:
SELECT DISTINCT mp3id FROM band_downloads WHERE userid=9 ORDER BY id DESC;и
SELECT DISTINCT band_downloads.mp3id, FROM band_downloads,band_mp3 WHERE band_downloads.userid=9 AND band_mp3.id=band_downloads.mp3id ORDER BY band_downloads.id DESC;Во втором случае Вы можете в MySQL 3.23.x получить две идентичных строки в наборе результатов (потому, что скрытый столбец 'id' может отличаться). Обратите внимание, что это случается только для запросов, где Вы не имеете ORDER BY в результате, что вообще-то неправильно с точки зрения стандарта ANSI SQL.
rollback
), некоторые вещи ведут себя немного иначе, чем в других
серверах SQL. Это только должно гарантировать, что MySQL никогда не должен
делать обратную перемотку для команд SQL. Это может быть иногда немного
неуклюже, поскольку значения столбца должны проверяться прикладной
программой, но это фактически даст Вам хорошее увеличение быстродействия,
поскольку это позволяет MySQL делать некоторые оптимизации, которые иначе
были бы невозможны или очень трудны. Если Вы устанавливаете столбец к
неправильному значению, MySQL будет, вместо того, чтобы делать обратную
перемотку, сохранять самое лучшее возможное
значение в столбце.
NULL
, который не берет
значения NULL
, MySQL сохранит 0 или ''
(пустую
строку). Это поведение может, однако, быть изменено с опцией компиляции
-DDONT_USE_DEFAULT_FIELDS.
DATE
и DATETIME
. Например, 2000-02-31 или
2000-02-00. Если дата полностью неправильна, MySQL сохранит в столбце
специальное значение даты 0000-00-00.
enum
к неподдерживаемому значению,
это будет установлено к значению ошибки 'empty string' с числовым значением 0.
PROCEDURE
на запросе, который возвращает
пустой набор, в некоторых случаях PROCEDURE
не будет
трансформировать столбцы.
MERGE
не проверяет, имеют ли основные
таблицы совместимые типы.
NaN
,
-Inf
и Inf
в double. Использование их вызовет
проблемы при попытке экспортировать и импортировать данные. Вы должны как
промежуточное решение изменить NaN
на NULL
(если
возможно), а -Inf
и Inf
соответственно к
минимальному и максимальному возможным значениям double
.
LIMIT
на отрицательных числах превращается в очень большие
положительные числа, что ошибочно.
ALTER TABLE
, чтобы сначала добавить
индекс UNIQUE
к таблице, используемой в таблице типа
MERGE
, и затем использовать ALTER TABLE
, чтобы
добавить нормальный индекс уже на таблице MERGE
, порядок ключей
будет иным для таблиц, если имелся старый не уникальный ключ в таблице. Это
потому, что ALTER TABLE
помещает ключи UNIQUE
перед
нормальными ключами, чтобы обнаружить двойные ключи как можно раньше.Следующее представляет известные ошибки в более ранних версиях MySQL:
DROP
TABLE
на таблице, которая является одной среди многих таблиц, которые
блокированы с помощью LOCK TABLES
.
LOCK table
с WRITE
FLUSH TABLES
UPDATE
, который модифицировал ключ
с помощью WHERE
на том же самом ключе, возможно, потерпел
неудачу потому, что та же самая строка использовалась для поиска:
UPDATE tbl_name SET KEY=KEY+1 WHERE KEY > 100;Обойти это можно так:
mysql> UPDATE tbl_name SET KEY=KEY+1 WHERE KEY+0 > 100;Это будет работать потому, что MySQL не будет использовать индекс на выражениях в предложении
WHERE
.
Для изучения ошибок, специфических для конкретной платформы, изучите разделы по компиляции и портированию.
Этот раздел описывает поддержку MySQL и меры патентования:
Формальные условия лицензии GPL могут быть найдены в сети или в разделе "Приложение 4. GNU GENERAL PUBLIC LICENSE ". В основном, стратегия патентования и интерпретация GPL авторами следующие:
Обратите внимание, что старшие версии MySQL все еще используют более строгую лицензию. Так что изучите соответствующую документацию по адресу http://www.mysql.com/support/arrangements/mypl.html. Если Вы нуждаетесь в коммерческой лицензии потому, что лицензия GPL не удовлетворяет Вашу прикладную программу, Вы можете купить ее на сайте https://order.mysql.com.
Для нормального внутреннего использования MySQL не стоит ничего. Вы не должны никому ничего платить за некоммерческое использование пакета.
Лицензия требуется если:
Лицензия НЕ требуется если:
GNU Library General Public License
. Клиент командной строки
mysql
включает код из библиотеки readline
, которая
находится под GPL
.
Для обстоятельств, при которых лицензия MySQL требуется, Вы нуждаетесь в
лицензии на машину, которая выполняет сервер mysqld
. Однако,
машина с несколькими CPU считается одной машиной, и нет никаких ограничение
на число серверов MySQL, выполняемых на ней, или на число клиентов,
одновременно связанных с ней!
Если Вы имеете любые вопросы относительно того, требуется или нет лицензия для Вашего специфического использования MySQL, пожалуйста, прочитайте это снова, а затем войдите в контакт с авторами.
Если Вам требуется лицензия MySQL, самый простой способ купить ее состоит в том, чтобы использовать форму лицензии на безопасном сервере MySQL по адресу https://order.mysql.com. Другие формы оплаты обсуждены в разделе "1.3.4.1 Информация об оплате".
Имеется несколько различных авторских прав на дистрибутив MySQL:
mysqlclient
, запатентован под LGPL
, и
программы в каталоге client под GPL. Каждый файл имеет заголовок,
который показывает, которое авторское право используется для этого файла.
getopt
охвачены
GNU LIBRARY GENERAL PUBLIC LICENSE. Подробности в разделе
"Приложение 5. GNU LESSER
GENERAL PUBLIC LICENSE".
regexp
)
охвачены авторским правом Berkeley-стиля.
readline
лицензируются по GNU GENERAL PUBLIC LICENSE. Подробности в разделе
"Приложение 4. GNU GENERAL PUBLIC LICENSE
". Она также доступна как файл COPYING в дистрибутивах.Одна цель состоит в том, что библиотека пользователей SQL должна быть достаточно свободной, чтобы возможно было добавить поддержку MySQL в коммерческие программы без лицензии. По этой причине авторы выбрали лицензию LGPL для кода пользователя.
Это означает, что Вы можете использовать пакет свободно с любо й программой, которая применяет любую из свободных программных лицензий. MySQL также абсолютно свободен для любого конечного пользователя для его личного пользования.
MySQL Version 3.22 все еще использует более строгую лицензию. Подробности есть в документации по ней.
Этот раздел описывает некоторые примеры ситуаций, показывая, должны или нет Вы лицензировать сервер MySQL.
Обратите внимание, что одиночная лицензия MySQL покрывает любое число CPU
и серверов mysqld
на одной машине! Не имеется никакого
искусственного ограничения числа клиентов, которые могут работать с сервером.
Чтобы определить, нуждаетесь или нет Вы в лицензии MySQL при продаже Вашей прикладной программы, Вы должны спросить себя, зависит ли соответствующее функционирование Вашей прикладной программы от использования MySQL, и включаете ли Вы сервер MySQL в поставку программы. Имеется несколько случаев:
mysqld
.
Internet Service Providers (ISP) часто ставят серверы MySQL для своих заказчиков. По лицензии GPL это не требует покупки лицензии.
С другой стороны, авторы поощряют использование тех ISP, которые имеют поддержку MySQL, поскольку это даст им возможность консультироваться по проблемам с СУБД у своего провайдера.
Всем таким ISP стоит подписаться на рассылку announce
, чтобы
они могли знать фатальные проблемы, которые могут быть релевантны для их
инсталляций пакета MySQL.
Обратите внимание, что, если ISP не имеет лицензию для MySQL, он должен дать заказчикам по крайней мере доступ для чтения к источнику установки MySQL так, чтобы заказчик мог проверить, что все исправлено правильно.
Если Вы используете MySQL вместе с Web-сервером под Unix, Вы не должны покупать для этого лицензию.
Это верно, даже если Вы выполняете коммерческий Web-сервер, который использует MySQL потому, что Вы не продаете вложенную версию MySQL самостоятельно. Однако, в этом случае авторы хотели бы, чтобы Вы приобрели поддержку MySQL потому, что пакет MySQL помогает Вашему предприятию.
Текущие (актуальные) цены на лицензии показываются ниже. Чтобы сделать покупку, посетите сайт https://order.mysql.com.
Если Вы оплачиваете кредитной карточкой, денежная единица: EURO (European Union Euro), так что цены немного отличаются.
Количество лицензий | Цена одной копии |
1-9 | 230 EURO |
10-24 | 138 EURO |
25-49 | 117 EURO |
50-99 | 102 EURO |
100-249 | 91 EURO |
250-499 | 76 EURO |
500-999 | 66 EURO |
Для большого объема (OEM) покупок, пожалуйста, войдите в контакт с sales@mysql.com.
Для приобретений OEM, Вы должны действовать как посредник для возможных проблем или запросов расширения от ваших пользователей. Авторы также требуют, чтобы OEM-заказчики имели по крайней мере расширенный контракт поддержки электронной почты. Обратите внимание, что лицензии OEM применимы только к пакетам, где пользователь не имеет прямой доступ на сервер MySQL (встроенные системы). Другими словами, сервер MySQL должен использоваться только с Вашей прикладной программой, но не с другими.
Если Ваша программа должна быть дешевой, свяжитесь с разработчиками пакета и изложите ситуацию (цены, оценки предполагаемого рынка и прочее, что имеет отношение к вопросу). Торг уместен.
Полноценная лицензия не представляет собой соглашение поддержки и включает очень маленькую поддержку. Это означает, что авторы пробуют отвечать на любые релевантные вопросы. Если ответ находится в документации, они направят Вас к соответствующему разделу. Если Вы не приобрели лицензию или поддержку, они, вероятно, не будут отвечать вообще.
Если Вы обнаруживаете то, что рассматривается реальная ошибка, ее скорей всего исправят в любом случае. Но если Вы оплачиваете поддержку, это ускорит процесс исправления ошибки.
Более всесторонняя поддержка продается отдельно. Описание того, что включает каждый уровень поддержки, даны в разделе "1.3.5 Типы коммерческой поддержки". Цены для различных типов коммерческой поддержки показываются ниже. Цены указаны в EURO (European Union Euro).
Тип поддержки | Цена годовой подписки на поддержку этого типа |
Базовая поддержка электронной почты | EURO 200 |
Расширенная поддержка электронной почты | EURO 1000 |
Login-поддержка | EURO 2000 |
Расширенная Login-поддержка | EURO 5000 |
Телефонная поддержка | EURO 12000 |
Вы можете перейти на более высокий уровень поддержки, оплатив разницу в цене между уровнями.
Авторы обеспечивают также и телефонную поддержку (обычно аварийную, но и 24/7 тоже). Эта опция поддержки не имеет фиксированную цену, а бывает заключена в зависимости от ситуации. Если Вы заинтересованы этой опцией, Вы можете сообщать относительно Ваших потребностей по e-mail sales@mysql.com.
Обратите внимание, что, поскольку коммерческий штат фирмы очень занят, может потребоваться некоторое время, пока Ваш запрос обработают.
В настоящее время поддерживаются кредитные карточки, чеки или SWIFT.
Оплата должна быть сделана на:
Postgirot Bank AB 105 06 STOCKHOLM, SWEDEN MySQL AB BOX 6434 11382 STOCKHOLM, SWEDEN SWIFT address: PGSI SESS Account number: 96 77 06 - 3
Определите: лицензия и/или поддержка, Ваше имя и адрес электронной почты.
В Европе и Японии Вы можете использовать платеж EuroGiro (который должен быть менее дорог) к тому же самому счету.
Если Вы хотите оплачивать чеком, заполните его на ``MySQL Finland AB'' и отправьте по почте на адрес:
MySQL AB BOX 6434, Torsgatan 21 11382 STOCKHOLM, SWEDEN
Если Вы хотите оплачивать кредитной карточкой через Internet, Вы можете использовать безопасную форму лицензии MySQL AB на https://order.mysql.com.
Вы можете также отпечатать копию формы лицензии, заполнить ее и отправить по факсу на:
+46-8-729 69 05
Если Вы хотите, чтобы Вам выставили счет, Вы можете использовать форму
лицензии и написать ``bill us'' в поле комментария. Вы можете также отправить
сообщение на адрес sales@mysql.com
(но НЕ на mysql@lists.mysql.com
!) с Вашей
информацией о компании и попросить, чтобы авторы выставили счет Вам.
Для коммерческого лицензирования, пожалуйста, войдите в контакт с группой лицензирования MySQL. Наилучший метод для этого: послать e-mail на адрес licensing@mysql.com. Факсы также возможны, но их обработка может занять намного большее время (факс: +46-8-729 69 05).
Если Вы представляете бизнес, который заинтересован в партнерстве с MySQL, пожалуйста, пошлите электронную почту на адрес partner@mysql.com.
Для своевременных и точных ответов на технические вопросы относительно MySQL Вы должны заказать один из контрактов поддержки. Поддержка MySQL обеспечивается разработчиками MySQL, так что стандарт чрезвычайно высок.
Если Вы заинтересованы размещением рекламы на Web-сайте MySQL, пожалуйста, пошлите электронную почту на адрес advertising@mysql.com.
Если Вы заинтересованы любой из работ, перечисленных в разделе работ ( http://www.mysql.com/development/jobs), пожалуйста, пошлите электронную почту на адрес jobs@mysql.com.
Для общего обсуждения среди пользователей пакета, пожалуйста, направьте сообщение в соответствующий список рассылки. Их перечень есть на http://www.mysql.com/documentation/lists.html.
Для вопросов или комментариев относительно работ или содержания Web-сайта, пожалуйста, пошлите электронную почту на webmaster@mysql.com.
Следующее всегда верно для всех параметров поддержки:
Базовая поддержка электронной почты очень недорогая опция поддержки и вообще-то скорее способ поддержать разработчиков, чем помочь клиентам... В значительной мере это окупает работу списков рассылки.
На этом уровне поддержки списки рассылки по-прежнему являются основной коммуникацией. То есть, пишите в них о своих проблемах, выбирая соответствующий теме список (вдруг кто-то уже эту проблему решил?). Однако, покупая базовую поддержку электронной почты, Вы также имеете доступ к mysql-поддержке по адресу mysql-support@mysql.com, который не доступен как часть минимальной поддержки, которую Вы получаете, просто покупая лицензию MySQL. Это означает, что для особенно критических вопросов, Вы можете послать сообщение на mysql-support@mysql.com. Если сообщение содержит чувствительные данные, Вы должны писать только на mysql-support@mysql.com.
ПОМНИТЕ! ВСЕГДА включайте Ваш код регистрации и дату окончания, когда Вы посылаете сообщение на mysql-support@mysql.com.
Обратите внимание, что, если Вы столкнулись с критической воспроизводимой ошибкой, и, согласно правилам, отослали сообщение о ней на bugs@lists.mysql.com, разработчики будут пробовать исправить ее как можно скорее, независимо от Вашего уровня поддержки! Подробности в разделе "1.4.1 Как сообщать об ошибках и проблемах".
Базовая поддержка электронной почты включает следующие типы обслуживания:
Расширенная поддержка электронной почты включает все из базовой поддержки электронной почты с этими добавлениями:
mysqld
(и
запросов) для Вашей конкретной ситуации.Login-поддержка включает все, что входит в расширенную поддержку электронной почты, но с добавлениями, которые перечислены ниже:
Расширенная Login-поддержка включает все из предыдущего типа поддержки, но уже с этими добавлениями:
mysql> select MY_FUNC(col1,col2) from table;
Телефонная поддержка как обычно включает весь предыдущий уровень поддержки, но еще и с этими добавлениями:
MySQL
, которым Вы можете звонить,
когда Вы имеете критическую проблему.
MySQL
, чтобы перезвонить в течение 48 часов, чтобы обсудить
возникшую проблему с пакетом.Чтобы получить поддержку для таблиц типов BDB
и
InnoDB
Вы должны оплатить дополнительно по 30% от стандартной
цены поддержки за каждый из драйверов таблицы, для которых Вы хотели
бы иметь поддержку.
В MySQL AB
помогут Вам создать соответствующий отчет ошибки
для драйвера таблицы и представить его на рассмотрение разработчикам
специфического драйвера таблицы. Авторы пакета будут также стараться
гарантировать, что Вы получите своевременный ответ или решение от
разработчиков драйвера таблицы.
Имейте в виду, что разработчики самого пакета не несут ответственности за разработчиков дополнительных драйверов. Несмотря на то, что они, само собой, приложат все усилия к решению проблемы, не гарантируется, что оно будет найдено очень быстро.
Перед отправкой отчета об ошибке или вопроса сделайте следующее:
Если Вы не можете найти ответ в руководстве или архиве, проконсультируйтесь с Вашим локальным экспертом MySQL. Если Вы все еще не можете найти ответ на Ваш вопрос, читайте следующий раздел относительно того, как послать запрос на mysql@lists.mysql.com.
Написание хорошего отчета об ошибке требует немало терпения, но при выполнении этого экономится много времени Вам и всем окружающим. Хороший отчет об ошибке, содержащий полный случай теста для ошибки, делает весьма вероятным скорейшее исправление проблемы. Этот раздел поможет Вам написать Ваш отчет так, чтобы Вы не тратили впустую Ваше время, выполняя действия, которые не могут ничем помочь.
Пользуйтесь скриптом mysqlbug
, чтобы генерировать отчет об
ошибке (или отчет относительно любой проблемы), если возможно. Сам
mysqlbug
может быть найден в каталоге scripts в
дистрибутиве исходного кода или (для двоичного дистрибутива) в каталоге
bin под Вашим каталогом установки MySQL. Если Вы не можете
использовать mysqlbug
, Вы должны все же включать всю необходимую
информацию, перечисленную в этом разделе.
Скрипт mysqlbug
помогает Вам сгенерировать отчет, определяя
многое из следующей информации автоматически, но если кое-что важное
отсутствует, пожалуйста, включите это в Ваше сообщение! Пожалуйста, читайте
этот раздел тщательно и удостоверьтесь, что вся информация, описанная здесь,
включена в Ваш отчет.
Нормальное место, чтобы сообщить ошибки и проблемы:
mysql@lists.mysql.com. Если Вы
можете создать случай теста, который ясно показывает ошибку, Вы должны его
послать на bugs@lists.mysql.com.
Обратите внимание, что в этом списке Вы должны только регистрировать полный
повторимый отчет ошибки, использующий скрипт mysqlbug
. Если Вы
работаете под Windows, Вы должны включить описание операционной системы и
версии MySQL. Предпочтительно, Вы должны проверить проблему при использовании
последнего устойчивого дистрибутива или версии для разработчика. Любой должен
быть способен повторить ошибку, используя только mysql test<script
на включенном случае теста или выполнить скрипт, который включен в
отчет ошибки. Все ошибки, зарегистрированные в списке bugs
,
будут исправлены или зарегистрированы в следующем выпуске MySQL! Если имеются
только маленькие изменения кода, в этом списке может быть опубликован патч.
Не забудьте, что можно ответить на сообщение, содержащее слишком много информации, но не на то, в котором полезных данных очень мало. Часто люди опускают факты потому, что они думают, что они знают причину проблемы и считают, что некоторые важнейшие детали не имеют значения. Хороший принцип: если Вы находитесь в сомнении относительно установления чего-либо, устанавливайте это! Это намного ускорит и упростит работу всем остальным.
Наиболее общие ошибки состоят в том, что люди не указывают номер версии MySQL или ОС (включая ее версию!), на которой работают. Это очень важная информация, и в 99 случаях из 100 отчет об ошибке без нее бесполезен! Часто спрашивают об ошибках, которые есть в старых версиях, но их уже нет в новых. Обновляйте софт, меньше будет проблем! Иногда ошибка платформно-зависимая, в таких ситуациях почти невозможно установить что-нибудь без того, чтобы знать операционную систему и номер версии платформы.
Не забудьте также обеспечивать информацию относительно Вашего компилятора, если это связано с проблемой. Часто люди находят ошибки в компиляторах и считают, что это проблемы MySQL. Большинство компиляторов вечно находятся в состоянии разработки и совершенствования. Чтобы определить, зависит или нет Ваша проблема от компилятора, авторы должны знать, какой именно компилятор используется. Обратите внимание, что каждая проблема компиляции должна быть расценена как отчет об ошибке и сообщена соответственно.
Самые лучшие отчеты такие, которые включают полный пример, показывающий как воспроизвести ошибку или проблему. Подробности в разделе "6.1.6 Создание случая теста, когда Вы испытываете искажение таблицы".
Если программа производит сообщение об ошибках, очень важно включить сообщение в Ваш отчет! Если мы пробуем искать данные из архива, используя сведения по этой программе лучше, чтобы присланное сообщение об ошибках точно соответствовало тому, которое программа производит. Вы никогда не должны пробовать запомнить то, что было в сообщении об ошибке, вместо этого скопируйте и вставьте сообщение в Ваш отчет!
Пожалуйста, не забудьте, что многие из тех, кто будет читать Ваш отчет,
применяют монитор в режиме с 80 символами в строке. Следовательно, при
изготовлении отчетов и примеров с использованием клиента mysql
Вы должны использовать опцию --vertical
(или завершать команду
комбинацией символов \G
) для вывода, который не превысит
доступную ширину для такого дисплея (например, инструкция EXPLAIN
SELECT
, подробности ниже).
Пожалуйста, включите следующую информацию в Ваш отчет:
mysqladmin
version
. mysqladmin
может быть найден в каталоге
bin под каталогом установок MySQL.
uname -a
.
mysqld
рухнул, Вы должны также сообщить запрос, который
потерпел крах. Вы можете обычно найти его, запуская mysqld
с
включеным протоколированием. Подробности в разделе
"6.1.5 Использование журналов, чтобы найти причину ошибок в mysqld".
mysqldump --no-data db_name tbl_name1 tbl_name2 ...
. Это очень
простой и мощный способ получить информацию относительно любой таблицы в базе
данных, которая поможет создать ситуацию, соответствующую той, что у Вас.
SELECT
Вы должны всегда включать вывод
EXPLAIN SELECT ...
и по крайней мере число строк, которые
производит инструкция SELECT
. Большее количество информации,
которую Вы даете относительно Вашей ситуации, делает более вероятным, что
кто-то сможет помочь Вам! Например, следующее представляет собой пример очень
хорошо составленного отчета об ошибке (это должно быть, конечно, создано с
помощью скрипта mysqlbug
). Обратите внимание на использование
признака конца оператора \G
для инструкций, чья ширина вывода
иначе превысила бы 80 символов:
mysql> SHOW VARIABLES; mysql> SHOW COLUMNS FROM ...\G < Вывод SHOW COLUMNS> mysql> EXPLAIN SELECT ...\G < Вывод EXPLAIN> mysql> FLUSH STATUS; mysql> SELECT ...; < Короткая версия вывода из SELECT, включая время, затраченное на обработку запроса> mysql> SHOW STATUS; < Вывод SHOW STATUS>
mysqladmin variables
extended-status processlist
, чтобы обеспечить некоторую информацию о
раболте Вашей системы.
mysqldump
, и создать файл README, который
описывает Вашу проблему. Создайте сжатый архив Ваших файлов, используя
tar
и gzip
(или zip
), и передайте его
по ftp
на
ftp://support.mysql.com/pub/mysql/secret. Затем пошлите короткое описание
проблемы на bugs@lists.mysql.com.
ftp
на
ftp://support.mysql.com/pub/mysql/secret. Если данные совершенно
секретны, используйте другие имена, но это крайние меры.
mysqld
, и что Вы используете, чтобы выполнить любые программы
клиента MySQL. Параметры к программам mysqld
и
mysql
, а также скрипту configure
, часто являются
ключами к решениям и очень нужны. Во всяком случае включить их не помешает.
Если Вы используете любые модули, типа Perl или PHP, пожалуйста, включите
также номера их версий.
mysqlaccess
, mysqladmin reload
и все сообщения об
ошибках, которые Вы получили при попытке подключить! Когда Вы проверяете Ваши
привилегии, Вы должны сначала выполнить mysqlaccess
. После этого
выполните mysqladmin reload version
и попробуйте соединиться с
программой, которая создает проблему. Команда mysqlaccess
есть в
каталоге bin под каталогом установки MySQL.
parse
error
), пожалуйста, проверьте Ваш синтаксис очень тщательно! Если Вы
не можете найти что-то неправильное в нем, чрезвычайно вероятно, что Ваша
текущая версия MySQL просто не поддерживает запрос, который Вы используете.
Если Вы применяете самую свежую версию, и руководство на
http://www.mysql.com/documentation/manual.php не покрывает синтаксис,
который Вы применили, значит MySQL не поддерживает Ваш запрос. Если
руководство покрывает синтаксис, который Вы используете, но Вы имеете старую
версию MySQL, Вы должны проверить хронологию изменения MySQL, чтобы увидеть,
когда синтаксис был реализован. В этом случае следует обновить версию.
myisamchk
или
CHECK TABLE
и REPAIR TABLE
.
mysqld
никогда не должен разрушить таблицу,
если ничто не уничтожило его посреди модификации. Если Вы можете найти
причину слета mysqld
, это сильно облегчит работу.
Направьте отчет на адрес соответствующей рассылки. Может кто-то еще испытал (и возможно решил) такую проблему. Если Вы подписаны на поддержку, пишите на mysql-support@mysql.com.
Когда ответы посланы Вам индивидуально, а не списку рассылки, считается хорошим тоном суммировать ответы и послать резюме в список рассылки, чтобы все могли с ним ознакомиться и решить свои проблемы.
Если Вы полагаете, что Ваш ответ представляет широкий интерес, Вы можете отправить его в список рассылки вместо того, чтобы ответить лично индивидууму, который Вас спросил. Пожалуйста, удостоверьтесь, что Ваш ответ не дублирует другой.
Попробуйте суммировать существенную часть вопроса в Вашем ответе, не надо цитировать все первоначальное сообщение. Пожалуйста, не отправляйте сообщения почты из Вашего браузера с включенным режимом HTML! Много пользователей не читают почту в браузере.
Этот раздел сравнивает MySQL с другими популярными базами данных.
Этот раздел первоначально был написан разработчиками MySQL. Не имеется никаких фактических ошибок, содержащихся в этом разделе, о которых я бы знал. Если Вы находите что-то неправильное, свяжитесь с авторами пакета по e-mail docs@mysql.com.
Перечень всех поддержанных ограничений, функций и типов есть на
crash-me
Web page по адресу
http://www.mysql.com/information/crash-me.php.
mSQL
mSQL
должен быть более быстрым в следующих случаях:
INSERT
в очень простые таблицы с немногими
столбцами и ключами.
CREATE TABLE
и DROP TABLE
.
SELECT
на чем-то, что не является индексом (просмотр таблицы
очень прост).mSQL
(и большинство
других реализаций SQL) на следующем:
SELECT
.
VARCHAR
.
SELECT
с многими выражениями.
SELECT
на больших таблицах.
mSQL
как только одно
подключение установлено, другие должны ждать его завершения независимо от
того, управляет ли подключение запросом, который является коротким или
длинным. Когда первое подключение завершается, следующее может обслуживаться.
mSQL
может стать патологически медленным,
если Вы изменяете таблицу в SELECT
. В эталонном наборе тестов
время выполнения порой отличалось в 15000 раз! Это из-за недостатка
оптимизатора объединения mSQL
, который не может упорядочить
таблицы в оптимальном порядке. Однако, если Вы помещаете таблицы точно в
правильном порядке mSQL
, а предложение WHERE
простое и использует индексные столбцы, объединение будет относительно
быстрым! Подробности в разделе "5.1.4
Набор тестов MySQL Benchmark Suite".
ORDER BY
и GROUP BY
.
DISTINCT
.
TEXT
и BLOB
.GROUP BY
и HAVING
.
mSQL
не поддерживает GROUP BY
вообще. MySQL
поддерживает полную версию GROUP BY
с HAVING
и
следующими функциями: COUNT()
, AVG()
,
MIN()
, MAX()
, SUM()
и
STD()
. COUNT(*)
оптимизирован, чтобы возвратить
данные очень быстро, если SELECT
получает данные из одной
таблицы, никакие другие столбцы не получены, и не имеется никакого
предложения WHERE
. MIN()
and MAX()
могут брать параметры-строки.
INSERT
и UPDATE
с вычислениями в фоновом
режиме. MySQL может делать вычисления в вызовах INSERT
или
UPDATE
. Например:
mysql> UPDATE SET x=x*10+y WHERE x<20;
SELECT
с функциями. MySQL имеет много функций (слишком
много, чтобы перечислить их здесь.MEDIUMINT
, который имеет
длину в 3 байта. Если Вы имеете 100000000 записей, экономия даже одного байта
на запись принципиальна. mSQL2
имеет более ограниченный набор
типов столбца, так что труднее получить маленькие таблицы.
mSQL
, так что мы не можем
говорить что-нибудь относительно этого.
mSQL
, а также менее дорог, чем mSQL
.
mSQL
, но с некоторыми добавленными свойствами.
mSQL
имеет JDBC-драйвер, но дел с ним имел мало, сравнивать их
трудно из-за отсутствия данных.
GROUP BY
и прочее пока не
реализованы в mSQL
, его разработчикам придется еще немало
поработать головой. Чтобы получить некоторую перспективу, Вы можете
просматривать файл HISTORY в mSQL
за последний год и
сравнивать это с разделом News в MySQL Reference Manual. Должно быть довольно
очевидно, что развивается наиболее быстро.
mSQL
и MySQL имеют много интересных инструментальных средств
от третьего лица. Поскольку портирование из mSQL
в MySQL легко,
почти все интересные прикладные программы, которые являются доступными для
mSQL
, также доступны для MySQL. MySQL приходит с простой
программой msql2mysql
, которая устанавливает различия в проверке
правописания между mSQL
и MySQL для используемых функций C API.
Например, это изменяет образцы msqlConnect()
на
mysql_connect()
. Преобразование программы пользователя с
mSQL
в MySQL обычно занимает несколько минут.mSQL
для MySQLСогласно опыту, требуется только несколько часов, чтобы преобразовать
инструментальные средства, типа msql-tcl
и
msqljava
, которые используют mSQL
C API так, чтобы
они работали с MySQL C API.
Процедура преобразования:
msql2mysql
на исходниках. Это
требует программы replace
, которая поставляется с MySQL.
Различия между mSQL
C API и MySQL C API:
MYSQL
как тип подключения
(mSQL
использует int
).
mysql_connect()
берет указатель на структуру
MYSQL
как параметр. Просто определите его глобально или
используйте malloc()
. mysql_connect()
также берет
два параметра для определения пользователя и пароля. Вы можете устанавливать
их к NULL, NULL
для заданного по умолчанию использования.
mysql_error()
берет указатель на структуру
MYSQL
как параметр. Только добавьте параметр для Вашего старого
кода msql_error()
, если Вы переносите старый код.
mSQL
возвращает только текстовое сообщение об ошибках.
mSQL
и MySQL клиент/серверИмеется достаточно различий, из-за которых невозможно (или по крайней мере непросто) поддерживать оба.
Наиболее значительные вещи, которыми протокол MySQL отличается от
mSQL
, перечислены ниже:
mSQL
2.0
SQL отличается от MySQLТипы столбцов:
MySQL
ENUM
: тип для одного значения из набора строк.
SET
: тип для многих значений из набора строк.
BIGINT
: тип для 64-разрядных целых чисел.
UNSIGNED
для целочисленных столбцов.
ZEROFILL
для целочисленных столбцов.
AUTO_INCREMENT
для целочисленных столбцов, которые
являются PRIMARY KEY
.
DEFAULT
для всех столбцов.mSQL2
mSQL
соответствуют типам столбцов MySQL,
показанным в таблице ниже:
Тип в mSQL | Тип в MySQL |
CHAR(len) | CHAR(len) |
TEXT(len) | TEXT(len) .
len максимальная длина. LIKE работает. |
INT | INT . С намного большим числом
параметров! |
REAL | REAL . Или FLOAT .
Доступны версии с 4 или 8 байтами. |
UINT | INT UNSIGNED |
DATE | DATE . Использует формат ANSI
SQL, а не собственный формат mSQL . |
TIME | TIME |
MONEY | DECIMAL(12,2) . Значение с
десятичной фиксированной точкой и двумя целыми числами. |
Создание индексов:
MySQL
CREATE TABLE
.
mSQL
CREATE INDEX
.Чтобы вставить уникальный идентификатор в таблицу:
MySQL
AUTO_INCREMENT
как спецификатор типа столбца.
mSQL
SEQUENCE
на таблице и выберите столбец
_seq
.Чтобы получить уникальный идентификатор строки:
MySQL
PRIMARY KEY
или UNIQUE
к таблице
и используйте его. Нововведение в Version 3.23.11: если PRIMARY
или UNIQUE
состоит только из одного столбца, и это имеет тип
integer, можно также обратиться к нему как к _rowid
.
mSQL
_rowid
. Заметьте, что
_rowid
может изменяться через какое-то время в зависимости
от многих факторов.Чтобы получить время, когда столбец был в последний раз изменен:
MySQL
TIMESTAMP
к таблице. Этот столбец будет
автоматически установлен к текущей (актуальной) дате и времени для инструкций
INSERT
или UPDATE
, если Вы не задаете столбцу
значение, или если Вы задаете ему значение NULL
.
mSQL
_timestamp
.Сравнения значений NULL
:
MySQL
NULL
всегда
вернет NULL
.
mSQL
mSQL
, NULL=NULL
вернет TRUE. Вы должны
изменить =NULL
на IS NULL
и
<>NULL
на IS NOT NULL
при переносе старого
кода с mSQL
на MySQL.Сравнение строк:
MySQL
BINARY
, который заставляет сравнения быть
выполненными согласно порядку ASCII, используемому на сервере MySQL.
mSQL
Нечувствительный к регистру поиск:
MySQL
LIKE
в зависимости от включаемых столбцов может быть как
чувствительным к регистру, так и нет. Если возможно, MySQL использует
индексы, если параметр LIKE
не начинается с группового символа.
mSQL
CLIKE
.Обработка конечных пробелов:
MySQL
CHAR
и
VARCHAR
. Если это поведение нежелательно, используйте столбцы
типа TEXT
, там пробелы остаются на месте.
mSQL
Предложение WHERE
:
MySQL
AND
будет
оценен перед OR
). Чтобы получить поведение mSQL
в
MySQL, используйте круглые скобки (как показано в примере ниже).
mSQL
mSQL
:
mysql> SELECT * FROM table WHERE a=1 AND b=2 OR a=3 AND b=4;Чтобы MySQL рассматривал его по методике, принятой в
mSQL
,
Вы должны добавить скобок:
mysql> SELECT * FROM table WHERE (a=1 AND (b=2 OR (a=3 AND (b=4))));
Контроль доступа:
MySQL
mSQL
При чтении следующего материала, пожалуйста, обратите внимание на то, что обе программы непрерывно развиваются и совершенствуются.
Следующее сравнение сделано в MySQL AB. Авторы старались быть максимально точными, но поскольку они знают MySQL вдоль и поперек, а вот PostgreSQL известен несколько хуже, некоторые вещи могли быть оценены не совсем верно.
MySQL и PostgreSQL представляют собой широко используемые программы, но с
различными целями проекта, даже при том, что они стараются поддерживать
совместимость с ANSI SQL. Это означает, что для некоторых прикладных программ
больше подходит MySQL, в то время как для других лучше все же PostgreSQL. При
выборе Вы должны сначала проверить, удовлетворяет ли набор свойств базы
данных вашу прикладную программу. Если Вы нуждаетесь в необработанном
быстродействии, MySQL, вероятно, Ваш самый лучший выбор. Если Вы нуждаетесь в
некоторых из дополнительных свойств, которые только PostgreSQL может
предложить, значит нужен PostgreSQL
.
При добавлении свойств к MySQL авторы стремятся сделать оптимальное, определенное решение. Код должен быть настолько хорош, чтобы не возникала потребность менять его в обозримом будущем. Авторы также не считают, что стоит жертвовать быстродействием ради свойств, но будут делать все возможное, чтобы найти такое решение, которое даст максимальную производительность. Это означает, что разработка идет медленнее, но конечный результат будет этого стоить. Этот вид разработки возможен только потому, что весь код сервера проверен одним или несколькими (в настоящее время двумя) авторами прежде, чем будет включен в сервер MySQL.
В MySQL AB считается, что частые выпуски могут предоставить новые свойства пользователям быстро. Из-за этого новый маленький выпуск появляется раз в три недели. Все выпуски проверены инструментальными средствами тестирования на большом количестве различных платформ.
PostgreSQL основан на ядре с большим количеством вкладчиков. Здесь имеет смысл располагать по приоритетам добавление новых свойств, вместо того, чтобы выполнить их оптимально потому, что можно всегда оптимизировать все, что надо позже, если возникнет потребность в этом.
Другое большое различие между MySQL и PostgreSQL: почти весь код в MySQL кодирован разработчиками, которые наняты MySQL AB. Исключительные ситуации: транзакции и библиотека regexp. Это находится в остром контрасте с PostgreSQL, где большинство кода написано большой группой людей.
Оба вышеупомянутых метода разработки имеют собственные преимущества и недостатки. В MySQL AB считают, что их модель лучше потому, что она дает лучшую непротиворечивость кода, более оптимальный и переносимый код, а также меньшее количество ошибок.
На странице crash-me Вы можете найти список тех конструкций базы данных и ограничений, которые можно обнаружить автоматически программой. Обратите внимание, однако, что многие числовые ограничения могут быть изменены с параметрами запуска для соответствующей базы данных. Вышеупомянутая web-страница является чрезвычайно полезной, когда Вы хотите гарантировать, что Ваши прикладные программы работают с различными базами данных, или когда Вы хотите перенести Вашу прикладную программу из одной СУБД в другую.
MySQL предлагает следующие преимущества перед PostgreSQL:
MySQL
вообще намного быстрее, чем PostgreSQL.
VACUUM()
время от времени, чтобы восстановить место после команд
UPDATE
и DELETE
и выполнять анализ статистики,
который является критическим, чтобы получить хорошую эффективность
PostgreSQL. VACUUM()
также необходим после добавления многих
новых строк к таблице. На занятой системе с большим количеством изменений,
VACUUM()
должен быть выполнен очень часто, в самых плохих
случаях даже много раз в день. В течение работы VACUUM()
,
который может занять часы, если база данных большая, никто ничего с базой
данных сделать не может. Группа разработки PostgreSQL имеет намерение
исправить это безобразие, но это будет не так-то просто!
PostgreSQL
.
ALTER TABLE
.
HEAP
или
MyISAM
. Подробности в разделе
"7 Типы таблиц MySQL".
BerkeleyDB
и InnoDB
.
Поскольку каждый драйвер транзакции выполняется по-разному при различных
условиях, это дает автору прикладной программы большее количество параметров,
чтобы найти оптимальное решение.
MERGE
дают Вам уникальный способ немедленно делать
просмотр набора идентичных таблиц и использовать их как одну. Это идеально
для систем, где Вы имеете журналы, которые Вы упорядочиваете, например, раз в
месяц. Подробности в разделе "7.2 Таблицы MERGE
".
INSERT
, SELECT
и UPDATE/DELETE
на базе
данных или таблице, MySQL позволяет Вам определять набор различных привилегий
на уровнях базы данных, таблицы и столбца. MySQL также позволяет определять
привилегию на комбинациях пользователей и хостов.
Недостатки MySQL в сравнении с PostgreSQL:
MyISAM
во многих случаях быстрее, чем блокировки страницы, блокировки строки или
versioning. Недостаток состоит в том, что, если каждый клиент не принимает
во внимание, как работает блокировка таблицы, одиночный долго работающий
запрос может блокировать таблицу для модификаций в течение длительного
времени. Этого можно избежать при проектировании прикладной программы. Если
это невозможно, рекомендуется перейти на использование транзакционных таблиц.
UPDATE
, а в MySQL 4.1 появятся вложенные выборы (subselects). В
MySQL 4.0 можно использовать многотабличное удаление, чтобы удалить данные из
многих таблиц сразу в то же самое время.PostgreSQL в настоящее время предлагает следующие преимущества над MySQL:
Обратите внимание, что в следующей таблице приведены версии, начиная с которых MySQL должен начать поддерживать то или иное свойство. К сожалению, планы разработчиков PostgreSQL мне неизвестны, так что таких данных по их пакету у меня нет.
Возможность | Версия MySQL |
Вложенные выборки | 4.1 |
Внешние ключи | 4.0 и 4.1 |
Просмотр (Views) | 4.2 |
Хранимые процедуры | 4.1 |
Расширяемые системные типы | Не планируется |
Unions | 4.0 |
Полные объединения | 4.0 или 4.1 |
Триггеры | 4.1 |
Constrainst | 4.1 |
Курсоры | 4.1 или 4.2 |
Расширяемые типы индексов, например, R-деревья | R-деревья планируются в версии не ниже 4.2 |
Таблицы с наследованием | Не планируются |
Другие резоны применения PostgreSQL:
Недостатки PostgreSQL в сравнении с MySQL:
VACUUM()
делает PostgreSQL непригодным, чтобы
использовать его в среде 24/7.
INSERT
,
DELETE
и UPDATE
.Для получения полного списка недостатков, Вы должны также исследовать первую таблицу в этом разделе.
На сегодняшний день есть только один эталоныый тест, который можно применить для оценки производительности MySQL, PostgreSQL и других баз данных. Его можно скачать с http://www.mysql.com/information/benchmarks.html.
Несмотря на многократные обращения к авторам пакета PostgreSQL с просьбой дополнить этот пакет тестов, ответа пока нет...
Эталонные тесты обычно выполняются опцией --fast
и без нее
для сравнения величин. Когда тест выполнен с опцией --fast
,
используются все расширенные возможности сервера для максимально возможного
ускорения процессов. Без этой опции сервер работает в нормальном режиме.
При работе PostgreSQL с --fast
вызывается
VACUUM()
после каждого сложного вызова UPDATE
и
DROP TABLE
, чтобы сделать базу данных компактней для следующих
вызовов SELECT
. Время работы вызова VACUUM()
измеряется отдельно от времени теста.
При выполнении PostgreSQL 7.1.1 с опцией --fast
на тесте
INSERT
сервер PostgreSQL рухнул, похоронив под своими обломками
и всю базу данных, причем она была так разрушена, что было невозможно
перезапустить сервер. После повторения такого инцидента во второй раз, было
решено отложить тестирование с опцией --fast
до выхода релиза.
Некоторые замечания по ходу тестов:
Очень легко сделать такой тест, который покажет отличные результаты на ЛЮБОЙ базе данных. Для этого всего-то надо использовать те возможности, в которых испытуемая база данных сильна, а конкуренты слабы. Такие места есть везде, в любой системе.
Этим способом можно показать, что MySQL быстрее PostgreSQL в 36 раз (проверено лично). Но такой результат нельзя рассматривать как честный. Более того, есть тесты, в которых PostgreSQL отстает от MySQL более, чем в 2000 раз. Это происходит на тех задачах, где PostgreSQL слабее MySQL. Если замерить производительность на них и сравнить с производительностью на задачах, дающих фору MySQL, примерно столько и выйдет.
Все это сказано для того, чтобы исключить сомнения в честности тестирования. Да, есть способы доказать превосходство любой СУБД над любой другой, но здесь сравнивали честно. MySQL делает много оптимизаций, которые по каким-либо причинам не делает PostgreSQL. Это тоже верно, SQL-оптимизатор очень сложный модуль, его можно оптимизировать годами.
При просмотре результатов эталонного теста, Вы должны искать те дела, которые Вы делаете в Вашей прикладной программе, и использовать только эти результаты, чтобы решить, которая база данных лучше всего подошла бы для Вашей прикладной программы. Эталонные результаты также показывают дела, в которых конкретная база данных не хороша, и должны дать Вам понятие относительно того, что Вам, вероятно, придется делать другими способами.
Есть один тест, разработанный Great Bridge, прочитать данные о нем можно на: http://www.greatbridge.com/about/press.php?content_id=4.
Это самый ужасный тест, какой мне только попадался. Он не только делает все, чтобы повысить результаты PostgreSQL. Он еще и сильно принижает все прочие базы данных.
ОБРАТИТЕ ВНИМАНИЕ: Разработчики PostgreSQL тут не при чем! Группа авторов этого пакета решительно осудила разработку Great Bridge, так что обвинять их просто не в чем.
Этот эталонный тест был осужден в большом количестве писем в списках рассылки, так что я здесь только коротко повторю, что там сделано не так.
VACUUM()
и настроили запуск тестов, чего
они не сделали ни для одной из других включаемых баз данных. При этом авторы
такого теста говорят о том, что этот процесс оптимизирует индексы и немного
освобождает дисковое пространство. Оптимизированные индексы немного
увеличивают эффективность. Но разработчиками MySQL было показано, что разница
в скорости работы множественных выборок на базе после применения
вакуумирования (VACUUM()
) и до него
отличается примерно в 10 раз.
SELECT
и JOIN
(особенно после вызова
VACUUM()
), но никуда не годится на INSERT
или
UPDATE
. Эталонные тесты указывают, что только
SELECT
были выполнены (или очень немного модификаций). Это могло
бы легко объяснять их хорошие результаты для PostgreSQL в этом тесте. Плохие
результаты для MySQL будут очевидны ниже в этом документе.
Tim Perdue, длительное время любитель PostgreSQL и неохотный пользователь MySQL издал сравнение на http://www.phpbuilder.com/columns/tim20001112.php3.
Было выявлено много странных вещей в его результатах. Например, он утверждал, что MySQL имел проблему с пятью пользователями в его тестах, когда известно, что имеются пользователи с подобными машинами как его, которые используют MySQL с 2000 одновременными подключениями, делающими по 400 запросов в секунду. В этом случае ограничение было в пропускной способности сети, а не в базе данных.
Похоже, он использовал ядро Linux, которое имело некоторые проблемы с многими потоками, например, ядра до 2.4, которые имели проблему с многими потоками на многопроцессорных системах.
Другая возможная проблема: старая версия glibc. Tim сам собирал пакет, а не использовал готовый дистрибутив с сайта разработчиков.
На все просьбы авторов пакета показать данные, на которых выполнялся тест, и выяснить, что пошло не так, ответа так и не последовало.
Через какое-то время возможности пакета меняются, и вышеупомянутые эталонные тесты больше не являются релевантными. MySQL теперь имеют пару разных драйверов таблицы с различными соотношениями быстродействия/параллелизма. Подробности в разделе "7 Типы таблиц MySQL". Было бы интересно увидеть, как вышеупомянутые тесты выполнятся с различными транзакционными типами таблиц в MySQL. PostgreSQL, конечно, также получил новые свойства. Поскольку вышеупомянутый тест не доступен публично, нет никакого способа узнать, как база данных повела бы себя в тех же самых тестах сегодня.
Заключение:
Единственные эталонные тесты, которые существуют сегодня в таком виде, что любой может скачать их и выполнить в MySQL и PostgreSQL, это эталонные тесты MySQL. Авторы этого пакета считают, что базы данных с открытыми исходниками должны быть проверены инструментальными средствами с открытым исходным кодом! Это единственный способ гарантировать, что никто не делает тесты, которых никто не сможет воспроизводить. Без знания всех фактов невозможно ответить на требования испытателя.
Более подробно о наборе тестов рассказано в разделе "5.1.4 Набор тестов MySQL Benchmark Suite".
Это приложение вносит в список свойства, которые планируется реализовать в новых версиях MySQL.
Все в этом списке указано приблизительно в том порядке, в каком это будет выполнено. Однако, коммерческие пользователи пакета до некоторой степени могут на этот порядок влиять. Кто платит деньги, тот и заказывает музыку.
В будущем пакет будет поддерживать полный стандарт ANSI SQL99, но с большим количеством полезных расширений.
Большинство базисных свойств, которые хотелось бы иметь в 4.0, уже выполнено. Теперь будут реализованы всякие полезные мелочи, а глобальные изменения подождут до версии MySQL 4.1.
.frm
). Это даст
возможность не исчерпать биты при добавлении большего количества параметров
таблицы. Старый формат пока поддерживается. Все недавно созданные таблицы,
однако, уже используют новый формат. Новый формат файла даст возможность
добавить новые типы столбца, большее количество параметров для ключей и
поддержку FOREIGN KEY
.
mysqld
в виде библиотеки. Это будет иметь тот же самый
интерфейс как стандартный клиент MySQL (с дополнительной функцией, чтобы
только установить параметры запуска) но будет быстрее (никакой TCP/IP или
сокетной поддержки), меньше и намного проще в использовании для встроенных
приложений и систем. Каждый будет способен определить во время компоновки
форму использования (клиент-сервер или стационарное приложение), только
определяя, которую библиотеку компоновать с программой. Такой
mysqld
будет поддерживать все стандартные свойства MySQL и можно
использовать это в поточном клиенте, чтобы выполнить различные запросы в
отдельных потоках системы.
RAND()
и переменными
пользователя @var
.
DELETE
на таблицах MyISAM
, чтобы использовать кэш
записи. Чтобы сделать это, авторы должны модифицировать кэш записи потоков
при изменении файла .MYD
.
SHOW COLUMNS FROM table_name
(используется клиентом
mysql
, чтобы позволить расширения имен столбца) не должен
открывать таблицу, а только файл определения. Это требует меньшего количества
памяти и работает намного быстрее.
SET CHARACTER SET
надо транслировать весь
запрос целиком, а не только строки из него. Это даст возможность
пользователям свободно применять все транслируемые символы в именах базы
данных, таблицы и столбцов.
gethostbyaddr_r()
так, чтобы
можно было менять ip_to_hostname()
, чтобы не блокировать другие
потоки при выполнении поиска в DNS.
record_in_range()
в таблицы
MERGE
, чтобы быть способным выбрать правильный индекс, когда
имеется много индексов. Авторы должны также расширить интерфейс информации,
чтобы получить распределение ключей для каждого индекса при выполнении
analyze
на всех подтаблицах.
SET SQL_DEFAULT_TABLE_TYPE=[MyISAM|INNODB|BDB|HEAP]
.select id from t where grp in
(select grp from g where u > 100)
select a.col1, b.col2 from (select max(col1) as col1 from root_table) a, other_table b where a.col1=b.col1Это могло бы быть выполнено, автоматически создавая временные таблицы для полученных таблиц для продолжительности запроса.
PREPARE
и посылки параметров для
mysqld
.
INSERT ... SELECT
для получения возможности
опционального применения конкурентных вставок.
RENAME DATABASE
. Чтобы сделать это безопасным
для всех драйверов таблицы, это должно работать следующим образом:
RENAME
.
SELECT MIN(column) ... GROUP BY
.
long_query_time
с точностью до
миллионных долей секунды.
mysql
с указанием используемой базы данных, даты, времени и т.д.
MERGE
.
myisampack
с сервером.
INSERT/DELETE/UPDATE
так, чтобы можно было восстанавливаться,
если индексный файл становится полным.
ALTER TABLE
на таблице, которая является
ссылкой на другой диск, надо создавать временные таблицы на этом диске.
DATE/DATETIME
, который обрабатывает
информацию часового пояса правильно, так, чтобы иметь дело с датами в
различных часовых поясах было бы намного проще, чем сейчас.
MyISAM
) без потоков.
INSERT SQL_CONCURRENT
и mysqld
--concurrent-insert
должны выполнять вставки в конец файла, если файл
блокирован на чтение.
FOREIGN
для ключей в файле
.frm.
DELETE
.
lockd
с современными ядрами Linux.
Если нет, надо исправить lockd
! Чтобы проверить это, запустите
mysqld
с параметром --enable-locking
и выполните
различные тесты fork*. Они не должны выдавать какие-либо ошибки, если
сервер lockd
работает.
LIMIT
, например,
LIMIT @a,@b
.
UPDATE
.
Например: UPDATE TABLE foo SET @a=a+b,a=@a,b=@a+c
GROUP BY
, как в следующем примере:
SELECT id, @a:=count(*), sum(sum_col)/@a FROM table_name
GROUP BY id
.
DEFAULT
к столбцам.
Выдавать ошибку при использовании инструкции INSERT
, которая не
содержит столбец, который не имеет значения DEFAULT
.
SELECT CACHED ...
.
mysql_query()
в строке без того, чтобы читать результаты или
давать хорошее сообщение об ошибках.
BIT
, чтобы он занимал в самом деле 1 бит,
(сейчас BIT
занимает 1 символ).
ctime()
не работает на
целом ряде систем FreeBSD.
IMAGE
в вызов LOAD DATA INFILE
для отмены обновления полей TIMESTAMP
и
AUTO_INCREMENT
.
LOAD DATE INFILE UPDATE
.
LOAD DATA
INFILE ... REPLACE INTO
.LOAD DATA INFILE
поумнее, например, так:
LOAD DATA INFILE file_name.txt INTO TABLE tbl_name TEXT_FIELDS (text_field1, text_field2, text_field3) SET table_field1=concatenate(text_field1, text_field2), table_field3=23 IGNORE text_field3Это может использоваться, чтобы перескочить над столбцами дополнительного пространства в текстовом файле, или обновить столбцы, основываясь на выражениях из прочитанных данных.
LOAD DATA INFILE 'file_name' INTO TABLE 'table_name' ERRORS TO
err_table_name
. Это заставило бы любые ошибки и предупреждения
регистрироваться в таблице err_table_name. Эта таблица имела бы структуру:
line_number - Номер строки в файле данных error_message - Сообщение error/warning Может быть, стоит добавить и data_line - Строка из файла данных
VARCHAR
(сейчас это уже
поддержано для таблиц MyISAM).
mysql
в netscape.
LOCK DATABASES
с разными опциями.
DECIMAL
и NUMERIC
не могут читать
числа в экспоненциальной форме: Field_decimal::store(const char
*from,uint len)
должен быть переделан, чтобы это исправить.
mysql.cc
, чтобы делать меньшее количество вызовов
malloc()
, когда имена полей хешированы.
t1 JOIN t2 ON ...
и
t1 JOIN t2 USING ...
. Сейчас Вы можете использовать его только с
вызовом LEFT JOIN
.
unsigned long long
.
show status
. Считать
инструкции INSERT
/DELETE
/UPDATE
.
Учитывать чтения и обновления, выборки из одной таблицы и выборки с
объединением, среднее число таблиц в выборе, количество запросов ORDER
BY
и GROUP BY
.
mysql
в середине запроса, Вы должны
открыть другое подключение и уничтожить старый запрос. Альтернативно попытка
должна быть сделана, чтобы обнаружить это на сервере.
SHOW
INFO FROM tbl_name
должно быть для базисной информации таблицы.
NATURAL JOIN
и UNION JOIN
select a from crash_me left join crash_me2 using (a)
. В этом случае a будет принято из таблицы crash_me.
ON
и USING
работали с типом
объединения JOIN
в оптимизаторе.
CONNECT BY PRIOR ...
для поиска в
иерархических структурах и списках.
RENAME DATABASE
mysqladmin copy database new-database
. Нужно добавить
команду COPY к mysqld
SHOW HOSTS
для печати информации относительно кэша hostname.
DELETE
и REPLACE
в команде
UPDATE
(это удалит строки, когда получена ошибка дублирования
ключа при модифицировании).
DATETIME
, чтобы сохранить доли секунд.
NULL
для расчетных
столбцов во избежание недоразумений.
SELECT COUNT(*)*(id+0) FROM table_name GROUP BY id
.
ALTER TABLE
, не должны прерывать
клиентов, выполняющих запрос INSERT DELAYED
.
UPDATE
, хранят
старые значения, которые у них были перед началом модификации.
myisamchk
, REPAIR
и OPTIMIZE TABLE
должны обрабатывать случаи, где файлы данных и/или индекса являются не
файлами, а символическими ссылками.
pread()
/pwrite()
в
Windows, чтобы задействовать параллельные вставки.
SUM(DISTINCT)
ANY()
, EVERY()
и
SOME()
. В ANSI SQL они работают только на булевых столбцах, но
можно расширять их, чтобы работать на любых столбцах/выражениях, применяя:
value == 0 -> FALSE value <> 0 -> TRUE.
MAX(column)
совпадает с типом
самого столбца column.
create table t1 (a DATE); insert into t1 values (now()); create table t2 select max(a) from t1; show columns from t2;
UPDATE
строку, если она существует, и INSERT
новую строку, если такой
строки пока нет. Вызов REPLACE
примерно так работает с
INSERT
/DELETE
.get_changed_tables(timeout,table1,table2,
...)
.
update items,
month set items.price=month.price where items.id=month.id;
memmap
когда
возможно. Сейчас только сжатые таблицы используют memmap
.
SHOW
.
timestamp
в файл регистрации модификации с помощью
записи SET TIMESTAMP=#;
.
order
(для ACCESS97).
UNION
, MINUS
, INTERSECT
и
FULL OUTER JOIN
. Сейчас работает только
LEFT OUTER JOIN
.
UNIQUE
на полях, которые могут быть
NULL
.
SQL_OPTION MAX_SELECT_TIME=#
, чтобы поместить ограничение
времени выполнения в запрос.
LIMIT
, чтобы восстановить (отыскать)
данные с конца, также должно работать.
safe_mysqld
:
согласно FSSTND (которому Debian пробует следовать), PID-файлы должны быть в
каталоге /var/run/<progname>.pid, а файлы протоколов в
/var/log. Было бы хорошо, если бы Вы могли помещать "DATADIR" в
первое объявление "pidfile" и "log", так что размещение этих файлов может
быть изменено одиночной инструкцией.
zlib()
для gzip
-файлов,
чтобы инструкция LOAD DATA INFILE
работала с ними.
BLOB
(частично уже решено).
AUTO_INCREMENT
, когда столбец
выставляется в 0. Надо использовать NULL
в таких случаях.
JOIN
с круглыми скобками.
GET_LOCK
.
При выполнении этого, нужно также обработать возможные тупики, которые это
изменение может представить.Время дано согласно количеству работы, это не реальное время.
Есть два способа добавить новую функцию в MySQL:
CREATE FUNCTION
и DROP FUNCTION
.
Подробности в разделе "3.1.1 Синтаксис
CREATE FUNCTION/DROP FUNCTION
".
mysqld
и становятся
доступными на постоянной основе.Каждый метод имеет свои проблемы:
Независимо от метода, который Вы используете, чтобы добавить новые
функции, они могут использоваться точно так же как местные функции типа
ABS()
или SOUNDEX()
.
CREATE FUNCTION/DROP FUNCTION
CREATE [AGGREGATE] FUNCTION function_name RETURNS {STRING|REAL|INTEGER} SONAME shared_library_name DROP FUNCTION function_name
Определяемые пользователем функции (user-definable function, UDF)
представляют собой способ расширить MySQL новой функцией, которая работает
подобно местным (встроенным) функциям MySQL типа ABS()
или
CONCAT()
.
AGGREGATE
новая опция для MySQL Version 3.23. Функция с
AGGREGATE
работает точно так же, как и встроенная функция
GROUP
, подобно SUM
или COUNT()
.
CREATE FUNCTION
сохраняет имя функции, тип и общедоступное
библиотечное имя в таблице mysql.func
системы. Вы должны иметь
привилегии insert и delete для базы данных
mysql
, чтобы создавать и удалять функции.
Все активные функции перезагружаются при каждом запуске сервера, если Вы
не запускаете mysqld
с опцией --skip-grant-tables
.
В этом случае инициализация пропущена, и UDF станут недоступны. Активная
функция представляет собой такую функцию, которая была загружена с помощью
CREATE FUNCTION
, но не была удалена через
вызов DROP FUNCTION
.
По поводу правил написания определяемых пользователем функций отсылаю Вас
к разделу "3.1 Добавление новой
функции, определяемой пользователем в MySQL". Для работы механизма UDF
функции должны быть написаны на C или C++, Ваша операционная система должна
поддерживать динамическую загрузку, и mysqld
должен быть
откомпилирован динамически (не статически).
Для работы механизма UDF функции должны быть написаны на C или C++, а Ваша операционная система должна поддерживать динамическую загрузку. Дистрибутив исходников MySQL включает файл sql/udf_example.cc, который определяет 5 новых функций. Консультируйтесь с этим файлом, чтобы видеть, как работают соглашения о вызовах UDF.
Чтобы mysqld
мог использовать UDF, Вы должны конфигурировать
MySQL с опцией --with-mysqld-ldflags=-rdynamic
. Причина этого
в том, что на многих платформах (включая Linux) Вы можете загружать
динамическую библиотеку (вызовом dlopen()
) из статически
скомпонованной программы, которая собрана с опцией
--with-mysqld-ldflags=-all-static
, но если Вы хотите
использовать UDF, который должен обратиться к символам из
mysqld
(подобно примеру methaphone
в
sql/udf_example.cc, который использует
default_charset_info
), Вы должны компоновать программу с
-rdynamic
. Подробности на man dlopen
.
Для каждой функции, которую Вы хотите использовать в инструкциях SQL, Вы
должны определить соответствующую функцию на C или на C++. В обсуждении ниже
имя ``xxx'' используется для имени функции примера. Здесь XXX()
(верхний регистр) указывает SQL-обращение к функции, и xxx()
(нижний регистр) указывает C/C++-обращение к функции.
Функции, которые Вы пишете на C/C++ для реализации интерфейса с
XXX()
:
xxx()
(обязательна)
SQL-тип | C/C++-тип |
STRING | char * |
INTEGER | long long |
REAL | double |
xxx_init()
(опциональна)
xxx()
. Это может использоваться
для:
XXX()
.
REAL
) максимального количества
десятичных чисел.
NULL
.xxx_deinit()
(опционально)
xxx()
. Это должно освободить
любую память, распределенную функцией инициализации.Когда инструкция SQL вызывает XXX()
, MySQL вызывает функцию
инициализации xxx_init()
, чтобы позволить ей выполнить любую
требуемую настройку, типа проверки параметра или распределения памяти. Если
xxx_init()
возвращает ошибку, инструкция SQL будет прервана с
сообщением об ошибке, причем главная и деинициализационная функции не будут
вызваны, что стоит иметь в виду при распределении памяти. Иначе основная
функция xxx()
будет вызвана один раз для каждой строки. После
того, как все строки были обработаны, вызывается функция
xxx_deinit()
, так что она может выполнить требуемую очистку.
Все функции должны быть безопасны для потоков (не только основная функция,
но и остальные: инициализация и деинициализация идут в поточном режиме!). Это
означает, что Вам не позволят распределить любые глобальные или менять
статические переменные! Если Вы нуждаетесь в памяти, Вы должны распределить
ее в xxx_init()
и непременно освободить в
xxx_deinit()
.
Основная функция должна быть объявлена как показано ниже. Обратите
внимание, что тип возврата и параметры отличаются в зависимости от того,
объявите ли Вы тип возврата функции SQL XXX()
как
STRING
, INTEGER
или REAL
в
вызове CREATE FUNCTION
:
Для функций типа STRING
:
char *xxx(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);
Для функций типа INTEGER
:
long long xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
Для функций типа REAL
:
double xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
Функции инициализации и деинициализации объявлены подобно этому:
my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void xxx_deinit(UDF_INIT *initid);
Параметр initid
передан всем трем функциям. Он указывает на
структуру UDF_INIT
, которая используется, чтобы передать
информацию между функциями. Члены структуры UDF_INIT
перечислены
ниже. Функция инициализации должна заполнить любые члены, которые она желает
изменить. Чтобы использовать значение по умолчанию для члена, оставьте его
неизменным. Перейдем к описанию:
my_bool maybe_null
xxx_init()
должна установить maybe_null
в
1
, если xxx()
может возвращать NULL
.
Значение по умолчанию 1
, если любой из параметров объявлен
как maybe_null
.
unsigned int decimals
1.34
, 1.345
и 1.3
,
значением по умолчанию будет 3, поскольку 1.345
имеет 3 десятичных цифры.
unsigned int max_length
initid->decimals
. Для числовых функций длина включает любой
знак или десятичные символы отметки.
char *ptr
initid->ptr
, чтобы
передать распределенную память между функциями. В xxx_init()
как
обычно распределите память и назначьте ее этому указателю:
initid->ptr=allocated_memory;В
xxx()
и xxx_deinit()
обратитесь к
initid->ptr
, чтобы использовать или освободить память.Параметр args
указывает на структуру UDF_ARGS
,
члены которой приведены ниже:
unsigned int arg_count
if (args->arg_count != 2) { strcpy(message,"XXX() requires two arguments"); return 1; }
enum Item_result *arg_type
STRING_RESULT
, INT_RESULT
и
REAL_RESULT
. Чтобы удостовериться, что параметры имеют данный
тип и возвращают ошибку, если они к нему не принадлежат, проверьте массив
arg_type
в функции инициализации. Например:
if (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != INT_RESULT) { strcpy(message,"XXX() requires a string and an integer"); return 1; }Вы можете использовать функцию инициализации, чтобы установить элементы
arg_type
к типам, которые Вы хотите получить. Это заставляет
MySQL привести параметры к тем типам для каждого обращения к
xxx()
. Например, чтобы определить первые два элемента как строку
и число, сделайте следующее в xxx_init()
:
args->arg_type[0] = STRING_RESULT; args->arg_type[1] = INT_RESULT;
char **args
args->args
сообщает информацию функции инициализации
относительно общего характера параметров, с которыми Ваша функция была
вызвана. Для постоянного параметра (константы) i
args->args[i]
указывает на значение параметра. Для
непостоянного параметра args->args[i]
равно 0
.
Постоянный параметр представляет собой выражение, которое использует только
константы, типа 3
, 4*7-2
или
SIN(3.14)
. Непостоянный параметр представляет собой выражение,
которое обращается к значениям, которые могут изменяться, типа имени столбца
или функций, которые вызваны с непостоянными параметрами. Для каждого
обращения основной функции args->args
хранит фактические
параметры, которые переданы для в настоящее время обрабатываемой строки.
Функции могут обратиться к параметру i
следующим образом:
STRING_RESULT
, данный как указатель строки
плюс длина, позволяет обработку двоичных данных или данных произвольной
длины. Содержание строки доступно как args->args[i]
, а длина
строки как args->lengths[i]
. Вы не должны считать, что
строка завершается нулевым символом.
INT_RESULT
Вы должны привести
args->args[i]
к типу long long
:
long long int_val; int_val = *((long long*) args->args[i]);
REAL_RESULT
Вы должны привести
args->args[i]
к типу double
:
double real_val; real_val = *((double*) args->args[i]);
unsigned long *lengths
lengths
указывает
максимальную длину строки для каждого параметра. Для каждого обращения к
основной функции lengths
хранит фактические длины любых
строковых параметров, которые переданы для строки, обрабатываемой в настоящее
время. Для параметров типов INT_RESULT
или
REAL_RESULT
lengths
хранит максимальную длину
параметра (как для функции инициализации).Функция инициализации возвратит 0
, если никакая ошибка не
произошла, и 1
в противном случае. Если ошибка происходит,
xxx_init()
должна сохранить сообщение об ошибке с нулевым
символом в конце в параметре message
. Сообщение будет возвращено
пользователю. Буфер сообщений имеет длину в MYSQL_ERRMSG_SIZE
символов, но Вы должны попробовать сохранить сообщение в 80 символах так,
чтобы это удовлетворило ширине стандартного экрана терминала.
Значение возврата основной функции xxx()
зависит от типа. Для
функций типов long long
и double
оно представляет
собой собственно функциональное значение. Строковые функции должны возвратить
указатель на результат и сохранить длину строки в параметрах
length
. Здесь result
представляет собой буфер
длиной в 255 байт. Установите их к содержанию и длине значения. Например:
memcpy(result, "result string", 13); *length=13;
Если Ваши функции строки должны возвратить строку длиннее, чем 255 байт,
распределите память для результата через malloc()
в функции
xxx_init()
или в xxx()
, а затем освободите память в
xxx_deinit()
. Вы можете сохранять распределенную память в слоте
ptr
структуры UDF_INIT
для повторного использования
в будущем обращении xxx()
. Подробности в разделе
"3.1.2.1 Соглашения о вызове UDF
".
Чтобы указывать значение возврата NULL
в основной функции,
установите is_null
в 1
:
*is_null=1;
Чтобы указать возврат ошибки в основной функции, установите параметр
ошибки (error
) в значение 1
:
*error=1;
Если xxx()
устанавливает *error
в 1
для любой строки, функциональное значение NULL
для текущей
строки и для любых последующих строк, обработанных инструкцией, в которой
вызывалась XXX()
. Причем, xxx()
не будет даже
запрашиваться для последующих строк. ПРИМЕЧАНИЕ: В MySQL до
версии 3.22.10 Вы должны установить
*error
и *is_null
:
*error=1; *is_null=1;
Файлы, выполняющие UDF, должны компилироваться и устанавливаться на сервере. Этот процесс описан ниже для примерного UDF-файла udf_example.cc, который включен в дистрибутив исходников MySQL. Этот файл содержит следующие функции:
metaphon()
возвращает мета-строку для строкового
параметра. Это похоже на soundex, но больше заточено под английский.
myfunc_double()
возвращает сумму ASCII-значений символов в
параметрах, поделенную на сумму длин этих параметров.
myfunc_int()
возвращает сумму длин параметров.
sequence([const int])
возвратит последовательность,
начинающуюся с заданного числа или с 1, если никакого числа задано не было.
lookup()
возвращает IP-адрес.
reverse_lookup()
возвращает hostname для IP-адреса. Функция
может быть вызвана со строкой "xxx.xxx.xxx.xxx"
или с 4 числами.
Динамически загружаемый файл должен компилироваться как разделяемый объектный файл, используя команду:
shell> gcc -shared -o udf_example.so myfunc.cc
Вы можете легко выяснять правильные параметры компилятора для Вашей системы, запуская такую команду в каталоге sql Вашего дерева исходных текстов MySQL:
shell> make udf_example.o
Вы должны выполнить команду компиляции, подобную одной из тех, что
отображает make
, за исключением того, что Вы должны удалить
опцию -c
близко к концу строки и добавить
-o udf_example.so
в самый конец строки. На некоторых системах
удалять -c
не надо, пробуйте.
Как только Вы скомпилируете общедоступный объект, содержащий UDF, Вы
должны установить его и сообщить MySQL о расширении функциональности.
Компиляция общедоступного объекта из udf_example.cc производит файл
с именем udf_example.so (точное имя может изменяться от платформы к
платформе). Скопируйте этот файл в некоторый каталог, где ищет файлы
ld
, например, в /usr/lib. На многих системах Вы можете
устанавливать системную переменную LD_LIBRARY
или
LD_LIBRARY_PATH
, чтобы указать каталог, где Вы имеете Ваши файлы
функции UDF. Руководство на dlopen
сообщает Вам, которую
переменную Вы должны использовать на Вашей системе. Вы должны установить это
в mysql.server
или в safe_mysqld
и перезапустить
mysqld
.
После того, как библиотека установлена, сообщите mysqld
относительно новых функций этими командами:
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so"; mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so"; mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so"; mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so"; mysql> CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so";
Функции могут быть удалены, используя DROP FUNCTION
:
mysql> DROP FUNCTION metaphon; mysql> DROP FUNCTION myfunc_double; mysql> DROP FUNCTION myfunc_int; mysql> DROP FUNCTION lookup; mysql> DROP FUNCTION reverse_lookup;
Инструкции CREATE FUNCTION
и DROP FUNCTION
модифицируют системную таблицу func
в базе данных
mysql
. Имя функции, тип и общедоступное библиотечное имя будут
сохранено в таблице. Вы должны иметь привилегии insert и
delete для базы данных mysql
, чтобы создавать и
удалять свои функции.
Вы не должны использовать CREATE FUNCTION
, чтобы добавить
функцию, которая уже была создана. Если Вы должны повторно установить
функцию, сначала удалите ее через вызов DROP FUNCTION
и затем
повторно установите ее с помощью CREATE FUNCTION
. Вы должны
сделать это, например, если Вы откомпилировали новую версию Вашей функции,
чтобы mysqld
обновил используемую им версию. Иначе сервер
продолжит применять старую версию.
Активные функции будут перезагружены при каждом перезапуске сервера, если
Вы не запускаете mysqld
с опцей --skip-grant-tables
.
В этом случае инициализация UDF будет пропущена, а UDF-функции станут
недоступными. Активная функция представляет собой функцию, загруженную через
CREATE FUNCTION
, но не удаленную DROP FUNCTION
.
Процедура для добавления новой встроенной функции описана ниже. Обратите внимание, что Вы не можете добавлять встроенные функции к двоичному дистрибутиву потому, что процедура включает изменение исходного текста MySQL. Вы должны скомпилировать MySQL самостоятельно из исходников. Также обратите внимание, что, если Вы мигрируете на другую версию MySQL (например, когда новая версия выпущена), Вы будете должны повторить процедуру с новой версией.
Чтобы добавить новую встроенную функцию MySQL, нужно:
sql_functions[]
.
sql_functions[]
и добавить
функцию, которая создает функциональный объект, в item_create.cc.
Смотрите "ABS"
и create_funcs_abs()
как пример.
Если функциональный прототип усложнен (например, берет переменное число
параметров), Вы должны добавить две строки к sql_yacc.yy. Каждая
указывает символ препроцессора, который yacc
должен определить
(это должно быть добавлено в начале файла). Затем определите функциональные
параметры и добавьте элемент с этими параметрами для правила синтаксического
анализа simple_expr
. Для примера, проверьте все местонахождения
ATAN
в sql_yacc.yy, чтобы увидеть, как это выполнено.
Item_num_func
или Item_str_func
, в зависимости от
того, возвращает ли Ваша функция число или строку.
double Item_func_newname::val() longlong Item_func_newname::val_int() String *Item_func_newname::Str(String *str)Если Вы наследуете Ваш объект от любого из стандартных элементов (подобно
Item_num_func
, Вы, вероятно, должны только определить одну из
вышеупомянутых функций и позволить родительскому объекту заботиться о других
функциях. Например, класс Item_str_func
определяет функцию
val()
, которая выполняет atof()
на значении,
возвращенном ::str()
.
void Item_func_newname::fix_length_and_dec()Эта функция должна по крайней мере вычислить
max_length
, исходя
из данных параметров. max_length
задает максимальное число
символов, которое функция может возвращать. Эта функция должна также
установить maybe_null=0
, если основная функция не может
возвращать значение NULL
. Функция может проверить, способен ли
любой из параметров возвращать NULL
, проверяя переменную
параметров maybe_null
. Вы можете изучить
Item_func_mod::fix_length_and_dec
в качестве типичного примера
того, как все это сделать.Все функции должны быть поточно-безопасными (другими словами, не используйте любые глобальные или статические переменные в функциях без того, чтобы защитить их через mutex).
Если Вы хотите возвращать NULL
из ::val()
,
::val_int()
или ::str()
Вы должны установить
null_value
в 1 и вернуть из функции 0.
Для объектной функции ::str()
имеются некоторые
дополнительные хитрости, которые надо знать:
String *str
обеспечивает буфер строки, который
может использоваться, чтобы хранить результат. Для получения большего
количества информации относительно типа String
обратитесь к
файлу sql_string.h.
::str()
должна возвратить строку, которая хранит
результат, или (char*) 0
, если результатом является
NULL
.
В MySQL Вы можете определять процедуру на C++, которая может обращаться и
изменять данные в запросе прежде, чем они отправятся к пользователю.
Модификация может быть выполнена на уровне строки или GROUP BY
.
Авторы пакета создали процедуру примера в MySQL Version 3.23, чтобы показать Вам, что там может быть выполнено.
Дополнительно авторы рекомендуют Вам посмотреть файл mylua, который Вы
можете найти в каталоге Contrib. Вы можете использовать язык LUA, чтобы
загрузить процедуру в mysqld
прямо во время выполнения.
analyse([max elements,[max memory]])
Эта процедура определена в sql/sql_analyse.cc. Она исследует результат, полученный из Вашего запроса, и возвращает анализ результатов:
max elements
(по умолчанию 256) задает максимальное
число разных значений, которые analyse
заметит в столбце. Это
используется, чтобы проверить оптимальность применения типа ENUM
.
max memory
(по умолчанию 8192) задает максимум памяти,
которую analyse
должен распределить на столбец при попытке найти
все отличные значения.SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]])
На сегодняшний день единственной документацией для этого является исходный код пакета.
Вы можете найти всю информацию относительно процедур, исследуя файлы:
Эта глава описывает много вещей, которые Вы должны знать при работе на коде MySQL. Если Вы планируете способствовать MySQL разработке, иметь доступ к коду отлаживаемых версий или хотите только следить за разработкой, следуйте командам в разделе " 2.3.4 Установка из дерева исходников для разработки". Если Вы заинтересованы внутренней организацией MySQL, Вы должны также подписаться на специальный список рассылки internals@lists.mysql.com.
Сервер MySQL создает следующие потоки:
process_alarm()
, чтобы завершить подключения,
которые были неактивны слишком долго.
mysqld
компилируется с -DUSE_ALARM_THREAD
,
специализированный поток, который обрабатывает тревоги, будет создан. Это
используется только на некоторых системах, где имеются проблемы с
sigwait()
, или если есть недостатки в применении кода
thr_alarm()
в прикладной программе без специализированного
потока обработки сигнала.
--flush_time=#
, будет создан еще
один специализированный поток, который сбрасывает таблицы на диск.
INSERT
DELAYED
, получает собственный поток.
--master-host
, будет запущен поток
репликации, чтобы читать и применять модификации с главного сервера.mysqladmin processlist
показывает только подключения, потоки
репликации и INSERT DELAYED
.
До недавнего времени основной набор теста был основан на составляющих
собственность данных заказчика и по этой причине не был публично доступен.
Единственный публично доступная часть процесса тестирования состояла из теста
crash-me
, эталонного теста Perl DBI/DBD, находящегося в каталоге
sql-bench
, и разнообразных тестов, размещенных в каталоге
tests
. Отсутствие стандартизированного публично доступного
набора тестов сделало трудным для пользователей и разработчиков тестирование
кода MySQL. Чтобы исправить эту ситуацию, авторы пакета создали совершенно
новую систему тестов, которая теперь включена в исходные и двоичные
дистрибутивы, начиная с Version 3.23.23.
Текущий набор тестов не проверяет все в MySQL, но должен охватить наиболее очевидные ошибки в обработка кода SQL, OS/library проблемы и тестирование репликации. Конечная цель состоит в том, чтобы иметь тесты, покрывающие 100% кода. Вы можете предоставить тесты, которые исследуют функциональные возможности, критичные для Вашей системы, поскольку это гарантирует, что все будущие выпуски MySQL будут хорошо работать с Вашими прикладными программами.
Система теста состоит из интерпретатора языков тестов
(mysqltest
), скрипта оболочки, чтобы выполнить все тесты
(mysql-test-run
), фактических случаев тестов, написанных на
специальном языке тестов и их ожидаемых результатов. Чтобы выполнить набор
теста на Вашей системе после построения, введите make test
или
mysql-test/mysql-test-run
из корневого каталога исходных
текстов. Если Вы установили двоичный дистрибутив, перейдите в корень
установки (например, /usr/local/mysql
) и скомандуйте
scripts/mysql-test-run
. Все тесты должны выполниться. Если этого
не произошло, пропобуйте выяснить почему и сообщите о проблеме, если это
ошибка в пакете MySQL. Подробности в разделе
"3.3.2.3 Как сообщать о проблемах и ошибках в
наборе тестов MySQL".
Если Вы имеете копию mysqld
на машине, где Вы хотите
выполнить набор тестов, Вы не должны останавливать ее, если она не использует
порты 9306
и 9307
. Если один из этих портов
применяется, Вы должны отредактировать mysql-test-run
и изменить
значения главного или подчиненного порта к тому, которое является доступным.
Вы можете запустить индивидуально каждый тест командой
mysql-test/mysql-test-run test_name
.
Если один тест свалился, проверьте работу mysql-test-run
с
опцией --force
, чтобы проверить, сбоят ли любые другие тесты.
Вы можете использовать язык mysqltest
, чтобы писать Ваши
собственные случаи теста. К сожалению, авторы пакета еще не написали полную
документацию для него. Вы можете, однако, рассматривать текущие случаи теста
и использовать их как пример. Следующие пункты должны помочь Вам:
mysql-test/t/*.test
;
)
инструкции и подобен вводу клиента командной строки mysql
.
Инструкция по умолчанию: запрос, который будет послан серверу MySQL, если он
не распознан как внутренняя команда (например, sleep
).
SELECT
, SHOW
, EXPLAIN
и прочие, нужно
предварить указанием @/path/to/result/file
. Файл должен
содержать ожидаемые результаты. Простой способ генерировать файл результата
состоит в том, чтобы выполнить mysqltest -r <
t/test-case-name.test
из каталога mysql-test
, а затем
отредактировать сгенерированные файлы результата, если необходимо
скорректировать их к ожидаемому выводу. В этом случае будьте очень осторожны
относительно добавления или удаления любых невидимых символов. Если Вы должны
вставить строку, удостоверьтесь, что поля отделяются позициями табуляции, и
имеется табуляция в конце. Вы можете использовать od -c
, чтобы
удостовериться, что Ваш текстовый редактор не добавляет что-нибудь
неожиданное в течение процесса редактирования.
mysql-test/r
и назвать их как
test_name.result
. Если тест производит больше, чем один
результат, Вы должны использовать test_name.a.result
,
test_name.b.result
и так далее.
--error error-number
. Здесь error-number может быть списком
возможных кодов ошибок, отделяемых запятыми (,
).
source include/master-slave.inc;
. Чтобы
переключаться между главной и подчиненной системами, используйте
connection master;
и connection slave;
. Если Вы
должны делать что-то на альтернативном подключении, Вы можете сделать
подключение connection master1;
для главной и
connection slave1;
для подчиненной системы.
let $1=1000; while ($1) { # Выполняем здесь запрос. dec $1; }
sleep
. Она поддерживает доли секунды, так что Вы можете указать
sleep 1.5;
, например, чтобы бездействовать 1.5 секунды.
mysql-test/t/test_name-slave.opt
. Для главной системы поместите
их в файл mysql-test/t/test_name-master.opt
.
Если Ваша версия MySQL не выполняет набор тестов, Вы должны сделать так:
mysqlbug
, чтобы
разработчики могли получить информацию относительно Вашей
системы и версии MySQL.
mysql-test-run
и
содержание всех .reject
файлов в каталоге
mysql-test/r
.
cd mysql-test mysql-test-run --local test-nameЕсли это терпит неудачу, то сконфигурируйте MySQL с опцией
--with-debug
и выполните mysql-test-run
с опцией
--debug
. Если это также терпит неудачу, закачайте файл
трассировки var/tmp/master.trace на
ftp://support.mysql.com/pub/mysql/secret, чтобы авторы могли исследовать это.
Пожалуйста, не забудьте также включить полное описание Вашей системы, версию
mysqld и параметры компиляции.
mysql-test-run
с опцией
--force
, чтобы увидеть, имеется ли любой другой тест, который
тоже терпит неудачу.
Result length mismatch
или
Result content mismatch
, это означает, что вывод теста не
соответствовал точно ожидаемому выводу. Это может быть ошибкой в MySQL, или
дело в том, что Ваша версия mysqld производит малость иные результаты при
некоторых обстоятельствах. Неудачные результаты теста будут помещены в файл с
тем же самым основным именем, что и файл результата, но с расширением
.reject
. Если Ваш случай теста терпит неудачу, Вы должны
сравнить два файла. Если Вы не можете увидеть, чем они отличаются, исследуйте
их с помощью od -c
и проверьте их длины.
mysql-test/var/log
для выяснения того, что не так.
mysql-test-run
с опциями --gdb
и/или
--debug
. Подробности в разделе
"6.1.2 Создание файлов трассировки
".
Если Вы не компилировали MySQL для отладки, вероятно, стоит сделать это.
Только определите параметр --with-debug
для вызова
configure
! Подробности в разделе
"2.3 Установка исходников MySQL".
Работающая библиотека потоков Posix необходима для сервера. В Solaris 2.5 мы используем Sun PThreads (местная поддержка потоков в 2.4 и более ранних версиях недостаточно хороша), а на Linux применен LinuxThreads (автор: Xavier Leroy, Xavier.Leroy@inria.fr).
Трудно выполнить перенос к новому Unix-варианту без хорошей местной поддержки потоков. Здесь может пригодиться пакет MIT-pthreads. Подробности в mit-pthreads/README и по адресу http://www.humanfactor.com/pthreads.
Дистрибутив MySQL включает исправленную версию Pthreads из MIT (с адреса http://www.mit.edu:8001/people/proven/pthreads.html). Это может использоваться для некоторых операционных систем, которые не имеют поддержки потоков в стандарте POSIX.
Также возможно использовать другой пакет уровня пользователя FSU Pthreads (подробности на http://www.informatik.hu-berlin.de/~mueller/pthreads.html). Эта реализация используется для SCO.
Пакет нуждается в компиляторе C++ (авторы применяют gcc
и
пробовали SparcWorks). Другой транслятор, который, как известно, работает,
Irix cc
.
Чтобы откомпилировать только клиента, вызовите
./configure --without-server
.
Не имеется в настоящее время никакой поддержки для компиляции только сервера, поскольку мало где это бывает нужно.
Если Вы должны переделать любой файл Makefile или скрипт
конфигурации, Вы должны получить Automake и Autoconf. Авторы использовали
automake-1.2
и autoconf-2.12
.
Теперь можно браться за дело:
/bin/rm */.deps/*.P /bin/rm -f confi6.cache aclocal autoheader aclocal automake autoconf ./configure --with-debug=full --prefix='your installation directory' # The makefiles generated above need GNU make 3.75 or newer. # (called gmake below) gmake clean all install init-db
Если Вы сталкиваетесь с проблемами, Вам, вероятно, придется делать некоторую отладку MySQL! Подробности в разделе "6.1 Отладка сервера MySQL".
ОБРАТИТЕ ВНИМАНИЕ: Прежде, чем Вы начнете отлаживать
mysqld
, сначала заставьте работать программы
mysys/thr_alarm
и mysys/thr_lock
. Это гарантирует,
что Ваша установка потоков работоспособна!
Если Вы используете некоторые функциональные возможности, которые являются
очень новыми в MySQL, Вы можете пробовать выполнять mysqld
с
опцией --skip-new
(которая отключит все новые, потенциально
опасные, функциональные возможности) или с --safe-mode
, которая
отключает много оптимизации, которая может вызывать проблемы.
Если mysqld
не хочет запускаться, Вы должны проверить, что Вы
не имеете любые файлы my.cnf
, которые сталкиваются с Вашей
установкой! Вы можете проверять параметры my.cnf
с помощью
вызова mysqld --print-defaults
и избегать их использования,
запуская mysqld --no-defaults ...
.
Если mysqld
начинает сильно загружать CPU или память, или он
виснет, Вы можете использовать mysqladmin processlist status
,
чтобы выяснить, выполняет ли кто-то запрос, который берет длительное время.
Стоит выполнить mysqladmin -i10 processlist status
, если Вы
испытываете проблемы с эффективностью работы, или когда новый клиент не может
соединиться с сервером, а остальные работают нормально.
Команда mysqladmin debug
сбрасывает в дамп некоторую
информацию относительно блокировок в использовании, занятой памяти и
запросов. Это может помочь решить некоторые проблемы. Эта команда также
обеспечивает некоторую полезную информацию, даже если Вы не компилировали
MySQL для отладки!
Если проблема состоит в том, что некоторые таблицы сильно замедляются, Вы
должны попробовать оптимизировать таблицу с помощью команды OPTIMIZE
TABLE
или вызова утилиты myisamchk
. Подробности в разделе
"4 Администрирование СУБД
MySQL". Вы должны также проверить медленные запросы командой
EXPLAIN
.
Вы должны также прочитать OS-специфический раздел в этом руководстве для изучения проблем, которые могут быть уникальными для Вашей среды. Подробности в разделе "2.6 Замечания по отдельным операционным системам".
Если Вы имеете некоторые очень специфические проблемы, Вы можете всегда
попробовать отлаживать MySQL. Чтобы сделать это, Вы должны конфигурировать
MySQL с опциями --with-debug
или --with-debug=full
.
Вы можете проверять, компилировался или нет MySQL с отладкой, командой
mysqld --help
. Если аргумент --debug
перечислен с
параметрами, то Вы имеете допускаемую отладку. Команда mysqladmin
ver
также вносит в список версию mysqld
как
mysql ... --debug
в этом случае.
Если Вы используете gcc или egcs, рекомендуемая строка выбора конфигурации:
CC=gcc CFLAGS="-O2" CXX=gcc CXXFLAGS="-O2 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-debug \ --with-extra-charsets=complex
Это позволит избежать проблемы с библиотекой libstdc++
и
исключительными ситуациями в C++ (много трансляторов имеют проблемы с ними),
и откомпилирует версию MySQL с поддержкой для всех наборов символов.
Если Вы подозреваете ошибку перекрытия памяти, Вы можете конфигурировать
MySQL с опцией --with-debug=full
, которая установит проверку
распределения памяти (SAFEMALLOC
). Однако, работа с
SAFEMALLOC
очень медленная, так что, если Вы получаете проблемы
эффективности, Вы должны запустить mysqld
с опцией
--skip-safemalloc
. Это отключит проверку памяти для всех
обращений к malloc
и free
.
Если mysqld
валится, когда Вы компилируете его с опцией
--with-debug
, Вы, вероятно, нашли ошибку транслятора или ошибку
синхронизации внутри MySQL. В этом случае Вы можете попробовать добавить
-g
к переменным CFLAGS
и CXXFLAGS
и
не использовать --with-debug
. Если mysqld
теперь
все равно валится, Вы можете по крайней мере присоединяться к нему с помощью
gdb
или использовать gdb
на файле дампа, чтобы
выяснить, что же там случилось.
Когда Вы конфигурируете MySQL для отладки, автоматически допускаются много
функций проверки безопасности, которые контролируют здоровье
mysqld
. Если они находят что-то непредвиденное, сообщение будет
записано в stderr
, который safe_mysqld
направляет к
файлу регистрации ошибок! Это также означает, что, если Вы имеете некоторые
непредвиденные проблемы с MySQL и используете дистрибутив исходников, Вы
должны конфигурировать MySQL для отладки!
В Windows MySQL mysqld.exe
по умолчанию компилируется с
поддержкой для файлов трассировки.
Если сервер mysqld
не запускается, или если Вы можете
заставить его очень быстро рухнуть, Вы можете попробовать создать файл
трассировки, чтобы найти проблему.
Чтобы сделать это, Вы должны иметь mysqld
, который
компилировался для отладки. Вы можете проверять это, выполняя mysqld
-V
. Если номер версии заканчивается -debug
, она
компилировалась с поддержкой для файлов трассировки.
Запустите сервер mysqld
с протоколом трассировки в
/tmp/mysqld.trace (или в C:\mysqld.trace под Windows):
mysqld --debug
Под Windows Вы должны также использовать параметр
--standalone
, чтобы не запустить mysqld
как сервис:
В DOS-окне введите:
mysqld --debug --standalone
После этого Вы можете использовать инструмент командной строки
mysql.exe
во втором окне DOS, чтобы воспроизвести проблему. Вы
можете завершить вышеупомянутый сервер mysqld
с помощью вызова
команды mysqladmin shutdown
.
Обратите внимание, что файл трассировки станет очень БОЛЬШИМ! Если Вы хотите иметь меньший файл трассировки, Вы можете использовать вызов:
mysqld --debug=d,info,error,query,general,where:O,/tmp/mysqld.trace
Это печатает только информацию с наиболее интересными отметками в /tmp/mysqld.trace.
Если Вы делаете отчет об ошибке относительно этой ситуации, пожалуйста, пошлите в соответствующий список рассылки только те строки из файла трассировки, в которых, кажется, что-то идет неправильно! Если Вы не можете локализовать неправильное место, Вы можете закачать по ftp весь файл трассировки вместе с полным отчетом ошибки на ftp://support.mysql.com/pub/mysql/secret, чтобы разработчики MySQL могли посмотреть это детально.
Файл трассировки сделан с применением пакета DBUG (автор Fred Fish). Подробности в разделе "6.3 Пакет DBUG".
На большинстве систем Вы можете также запустить mysqld
из
gdb
, чтобы получить большее количество информации, если
mysqld
терпит крах.
С несколькими старыми версиями gdb
под Linux Вы должны
использовать run --one-thread
, если Вы хотите отладить потоки
mysqld
. В этом случае Вы можете иметь только один активный поток
в каждый момент времени.
При запуске mysqld
под gdb, Вы должны отключить трассировку
стека с помощью опции --skip-stack-trace
, чтобы быть способными
захватить segfaults внутри gdb.
Очень сложно отладить MySQL под gdb
, если Вы делаете много
новых подключений в то время, как gdb
не освобождает память для
старых потоков. Вы можете избегать этой проблемы, запуская
mysqld
с параметром
-O thread_cache_size=max_connections+1
. В большинстве случаев
помогает только использование using -O thread_cache_size=5
!
Если Вы хотите получать дамп на Linux, если mysqld
падает с
сигналом SIGSEGV, Вы можете запустить mysqld
с опцией
--core-file
. Файл дампа может использоваться, чтобы сделать
обратную трассировку (backtrace), которая может помочь Вам выяснить, почему
именно mysqld
все же рухнул:
shell> gdb mysqld core gdb> backtrace full gdb> exit
Подробности в разделе "8.4.1 Что делать, если MySQL рушится".
Если Вы используете gdb 4.17.x или выше под Linux, Вы должны установить файл .gdb со следующей информацией, в Вашем текущем каталоге:
set print sevenbit off handle SIGUSR1 nostop noprint handle SIGUSR2 nostop noprint handle SIGWAITING nostop noprint handle SIGLWP nostop noprint handle SIGPIPE nostop handle SIGALRM nostop handle SIGHUP nostop handle SIGTERM nostop noprint
Если Вы имеете проблемы при отладке потоков с gdb, Вы должны загрузить gdb 5.x и попробовать применить эту версию. Новая реализация gdb очень сильно улучшила обработку потоков!
Имеется пример, как отладить mysqld:
shell> gdb /usr/local/libexec/mysqld gdb> run ... backtrace full # Do this when mysqld crashes
Включите вышеупомянутый вывод в почту, сгенерированную
mysqlbug
и отправьте на mysql@lists.mysql.com
.
Если mysqld
висит, Вы можете попробовать использовать
некоторые инструментальные средства системы подобно strace
или
/usr/proc/bin/pstack
, чтобы исследовать,
где mysqld
завис:
strace /tmp/log libexec/mysqld
Если Вы используете интерфейс Perl DBI
, Вы
можете включить информацию об отладке, используя метод trace
или
устанавливая системную переменную DBI_TRACE
.
На некоторых операционных системах, файл регистрации ошибок будет
содержать трассировку стека, если mysqld
неожиданно рушится. Вы
можете использовать это, чтобы выяснить, где (и возможно, почему) рухнул
mysqld
. Подробности в разделе "
4.9.1 Протокол ошибок". Чтобы получать трассировку стека, Вы не должны
компилировать mysqld
с опцией -fomit-frame-pointer
при использовании gcc. Подробности в разделе
"6.1.1 Компиляция MYSQL для
отладки".
Если файл ошибок содержит нечто вроде следующего:
mysqld got signal 11; The manual section 'Debugging a MySQL server' tells you how to use a stack trace and/or the core file to produce a readable backtrace that may help in finding out why mysqld died Attemping backtrace. You can use the following information to find out where mysqld died. If you see no messages after this, something went terribly wrong stack range sanity check, ok, backtrace follows 0x40077552 0x81281a0 0x8128f47 0x8127be0 0x8127995 0x8104947 0x80ff28f 0x810131b 0x80ee4bc 0x80c3c91 0x80c6b43 0x80c1fd9 0x80c1686
Вы можете найти, где именно mysqld
рухнул, следующим образом:
mysqld
:
nm -n libexec/mysqld > /tmp/mysqld.symОбратите внимание, что многие двоичные дистрибутивы MySQL приходят уже с вышеупомянутым файлом, именованным
mysqld.sym.gz
. В этом случае
Вы должны распаковать его командой:
gunzip < bin/mysqld.sym.gz > /tmp/mysqld.sym
resolve_stack_dump -s /tmp/mysqld.sym -n mysqld.stackЭто распечатает, где
mysqld
взорвался. Если это не помогает Вам
выяснить, почему произошла такая неприятность, Вы должны сделать сообщение об
ошибке и включать вывод из вышеупомянутого в отчет об ошибке. Обратите
внимание, однако, что в большинстве случаев это не будет помогать авторам
найти причину проблемы. Чтобы локализовать глюк в большинстве случаев нужно
знать запрос, который уничтожил mysqld
и предпочтительно иметь
тестовый пример так, чтобы авторы смогли повторить проблему! Подробности в
разделе "1.4.1 Как сообщать об
ошибках или проблемах".Обратите внимание, что перед стартом mysqld
с опцией
--log
Вы должны проверить все Ваши таблицы с помощью
myisamchk
. Подробности в разделе
"4 Администрирование СУБД
MySQL".
Если mysqld
падает или виснет, Вы должны запустить
mysqld
с опцией --log
. Когда mysqld
в очередной раз свалится, Вы можете исследовать конец журнала для выявления
запроса, который уничтожил mysqld
.
Если Вы используете --log
без имени файла, файл регистрации
будет сохранен в каталоге баз данных как 'hostname'.lo6. Обычно проблема
заключена в последнем запросе в журнале, но если возможно, проверьте это,
перезапуская mysqld
и выполняя найденный запрос из
инструментальных средств командной строки mysql
. Если запрос
работает нормально, Вы должны также проверить все сложные запросы, которые не
завершались на момент падения сервера.
Вы можете также попробовать команду EXPLAIN
на всех
инструкциях SELECT
, которые берут длительное время, чтобы
гарантировать, что mysqld
использует индексы правильно.
Подробности в разделе "5.2.1 Синтаксис
EXPLAIN
(получение информации о SELECT
)".
Вы можете находить запросы, которые берут длительное время, запуская
mysqld
с опцией --log-slow-queries
. Подробности в
разделе "4.9.5
Медленный файл регистрации".
Если Вы находите текст mysqld restarted
в файле регистрации
ошибок (обычно hostname.err), Вы, вероятно, нашли запрос, который
заставляет mysqld
падать. Если это случается, Вы должны
проверить все Ваши таблицы с помощью myisamchk
(подробности в
разделе "4
Администрирование СУБД MySQL"), и проверить запросы в журналах MySQL,
чтобы видеть, все ли работает. Если Вы находите запрос, который не намерен
выполняться, попробуйте сначала обновиться до самой новой версии MySQL. Если
это не помогает, и Вы не можете найти ничего подходящего в архиве рассылок
mysql
, Вы должны сообщить ошибку на
mysql@lists.mysql.com. Ссылки на
архив рассылок доступны на страничке
http://www.mysql.com/documentation.
Если Вы запустили mysqld
с аргументом
--with-myisam-recover
, MySQL автоматически проверит и попробует
отремонтировать таблицы MyISAM
, если они отмечены как 'not
closed properly' или 'crashed'. Если это случается, MySQL будет писать
соответствующую метку в файл hostname.err
: 'Warning:
Checking table ...'
, которая сопровождается записью: Warning:
Repairing table
, если таблица должна быть восстановлена. Если Вы
получаете много этих ошибок, без предыдущего падения mysqld
, то
что-то идет неправильно и должно быть исследовано далее.
Конечно, не хороший знак, если mysqld
падает неожиданно, но в
этом случае надо поискать причину его падения, а не причину появления заметки
Checking table...
в файле протокола.
Если Вы получаете разрушенные таблицы, или если mysqld
всегда
терпит неудачу после некоторых команд модификации, Вы можете проверить
воспроизводимость ситуации, делая следующее:
mysqladmin shutdown
).
myisamchk -s database/*.MYI
.
Восстановите любые неправильные таблицы командой
myisamchk -r database/table.MYI
.
mysqld
с аргументом --log-binary
.
Если Вы хотите находить запрос, который разрушает mysqld
, Вы
должны использовать --log --log-binary
.
mysqld
.
mysqld
без параметра
--log-binary
.
mysqlbinlog update-log-file|mysql
. Файл регистрации модификации
сохранен в MySQL каталоге баз данных под именем hostname-bin.#
.
mysqld
с вышеупомянутой командой, Вы нашли восстанавливаемую
ошибку, которая должна быть проста в устранении! Закачайте таблицы и двоичный
файл регистрации по FTP на
ftp://support.mysql.com/pub/mysql/secret и сообщите об ошибке на
bugs@lists.mysql.com, чтобы
проинформировать об имеющейся проблеме, и группа разработчиков MySQL устранит
ее как можно скорее.Вы можете также использовать скрипт mysql_find_rows
, чтобы
выполнить только некоторые из инструкций, если Вы хотите сузить проблему.
Чтобы отладить клиента MySQL с интегрированным пакетом отладки, Вы должны
конфигурировать MySQL с опциями --with-debug
или
--with-debug=full
. Подробности в разделе
"2.3.3 Типичные опции скрипта
configure
".
Перед запуском клиента Вы должны установить системную
переменную MYSQL_DEBUG
:
shell> MYSQL_DEBUG=d:t:O,/tmp/client.trace shell> export MYSQL_DEBUG
Это заставляет клиентуру генерировать файл трассировки в /tmp/client.trace.
Если Вы имеете проблемы с Вашим собственным кодом клиента, Вы должны
пытаться соединиться с сервером и выполнить Ваш запрос, используя клиента,
который, как известно, точно работает. Это делается запуском
mysql
в режиме отладки (предполагается, что Вы компилировали
MySQL с поддержкой режима отладки):
shell> mysql --debug=d:t:O,/tmp/client.trace
Это обеспечит полезную информацию в случае, если Вы отправляете по почте отчет об ошибке. Подробней процесс рассмотрен в главе "1.4.1 Как сообщать об ошибках и проблемах ".
Если Ваш клиент терпит крах в некотором коде, который выглядит абсолютно нормальным, Вы должны проверить, что Ваш включаемый файл mysql.h соответствует Вашему библиотечному файлу mysql. Очень частая ошибка: пытаются использовать старый файл mysql.h из старой установки с новой библиотекой MySQL.
Сервер и многие клиенты MySQL компилируются с пакетом DBUG, первоначально сделанным Fred Fish. Когда MySQL сконфигурирован для отладки, этот пакет делает возможным доступ к файлу трассировки. Подробности в разделе "6.1.2 Создание файлов трассировки ".
Для использования пакета отладки, вызовите программу с опцией
--debug="..."
или -#...
.
Большинство программ MySQL имеет заданную по умолчанию строку отладки,
которая будет использоваться, если Вы не определяете опцию
--debug
. Заданный по умолчанию файл трассировки обычно
/tmp/programname.trace
в Unix или
\programname.trace
под Windows.
Строка управления отладкой представляет собой следующую последовательность полей, отделяемых двоеточиями:
<field_1>:<field_2>:...:<field_N>
Каждое поле состоит из обязательного символа флажка, сопровождаемого факультативной "," и разделяемым запятыми списком модификаторов:
flag[,modifier,modifier,...,modifier]
В настоящее время распознанные символы флажка:
d | Включить вывод из макроса DBUG_<N> для текущего состояния. Может сопровождаться списком ключевых слов, который выбирает вывод только для макрокоманд DBUG с тем же самым ключевым словом. Пустой список ключевых слов подразумевает вывод для всех макрокоманд. |
D | Задержка после каждой линии вывода отладчика. Параметр
указывает число десятых долей секунды для задержки. То есть,
-#D,20 задает задержку в две секунды. |
f | Ограничивает отладку и/или трассировку списком имен функций. Обратите внимание, что пустой список отключит все функции. Соответствующий флажок "d" или "t" должен все же быть дан, поскольку этот флажок только ограничивает их действие, если они включены. |
F | Идентифицируют имя исходного файла для каждой строки отладки или трассирует вывод. |
i | Идентифицируют процесс с pid для каждой строки отладки или трассирует вывод. |
g | Включить профилирование. Создайте файл 'dbugmon.out', содержащий информацию, которая может использоваться, чтобы профилировать программу. Может сопровождаться списком ключевых слов, которые выбирают профилирование только для функций в этом списке. Пустой список подразумевает, что все функции подлежат профилированию. |
L | Идентифицирует номер строки исходного файла для каждой строки отладки или трассирует вывод. |
n | Выводит текущую глубину вложенности функции для каждой строки отладки или трассирует вывод. |
N | Номер каждой строки вывода dbu6. |
o | Переназначает выходной поток отладчика в файл. По умолчанию задан вывод в stderr. |
O | То же, что и O , но файл сбрасывается между
записями. То есть, после каждой записи файл закрывается, и снова открывается
только перед следующей записью. Тормозит, конечно, кошмарно, но зато
гарантирует сохранность данных в этом файле на случай слета системы. Что при
отладке не бесполезно... |
p | Ограничивает действия отладчика определенными процессами. Процесс должен быть указан в макросе DBUG_PROCESS и совпадать с одной из записей в списке действий отладчика. |
P | Выводит имя текущего процесса для каждой строки отладки или трассирует вывод. |
r | При установке нового состояния отладки не наследует предыдущее состояние вложенности функции. Полезно, когда вывод должен начаться в левом поле. |
S | Функция _sanity(_file_,_line_) для каждой отлаживаемой функции до _sanity() возвращает отличное от 0 значение. Обычно используется с safemalloc. Как задается это значение, и что оно вообще значит в документации не сказано, а опытным путем это установить не удалось. |
t | Включить функцию трассировки строк вызова и выхода (call/exit). Может сопровождаться списком, содержащим номер максимального уровня трассировки, вне которого никакого вывода не произойдет для отладочных или трассировочных макрокоманд. Умолчание задается при компиляции. |
Некоторые примеры строк управления отладкой:
-#d:t -#d:f,main,subr1:F:L:t,20 -#d,input,output,files:n -#d:t:i:O,\\mysqld.trace
В MySQL общие тэги для печати (с опцией d
) такие:
enter
, exit
, error
,
warning
, info
и loop
.
В настоящее время MySQL поддерживает блокировку таблицы только для типов
таблиц ISAM
/MyISAM
и HEAP
, а также
блокировки уровня страницы для таблиц BDB
. Подробности в разделе
"5.3.1 Как MySQL блокирует таблицы".
При работе с таблицами MyISAM
можно свободно смешивать
INSERT
и SELECT
без блокировок
(Versioning
).
Начиная с версии 3.23.33, Вы можете анализировать появление блокировки
таблицы на Вашей системе, проверяя системные переменные
Table_locks_waited
и Table_locks_immediate
.
Некоторые пользователи базы данных утверждают, что MySQL не может поддерживать большое число параллельных пользователей потому, что он испытывает недостаток блокировки уровня строки. Это может быть истинно для некоторых специфических прикладных программ, но не в общем случае. Как всегда, все зависит полностью от того, что прикладная программа делает, и каков образец доступа/модификации данных.
Плюсы блокировки строки:
Минусы блокировки строки:
GROUP BY
на большой части данных, или если требуется часто
просматривать целую таблицу.
Блокировки таблицы превосходят блокировки уровня страницы или отдельной строки в следующих случаях:
UPDATE table_name SET column=value WHERE unique_key# DELETE FROM table_name WHERE unique_key=#
SELECT
объединенный с INSERT
(иногда с
UPDATE
и DELETE
).
GROUP BY
на целой таблице без записи.
Другие параметры для блокировки уровня страницы/строки:
Versioning (подобно тому, что мы используем в MySQL для параллельных вставок), где Вы можете иметь одну запись в то же самое время, когда идет много чтений. Это означает, что база данных или таблица поддерживает различные представления данных в зависимости от того, когда процесс к ним обратился. Также известно под названиями "копии по запросу" или "копии на запись".
Копия по запросу во многих случаях намного лучше, чем блокировка уровня строки или страниц. Самый плохой случай, однако, использует намного больше оперативной памяти, чем при использовании нормальных блокировок.
Вместо того, чтобы использовать блокировку уровня строки, можно применить блокировки уровня прикладной программы. (Подобно get_lock/release_lock в MySQL). Это работает, конечно, только в хороших прикладных программах.
Имеются некоторые советы относительно блокировки:
На прикладной программе для web почти все клиенты делают большое количество выборов, очень немногие удаляют данные, модификации идут главным образом на ключах и вставках в некоторых специфических таблицах. Ядро MySQL ОЧЕНЬ хорошо настроено для этого.
Параллельные пользователи не проблема, если каждый из них не смешивает модификации и выборы, которые должны исследовать много строк в одной таблице.
Если смешиваются вставки и удаления на той же самой таблице, то
INSERT DELAYED
может сильно помочь.
Можно также использовать LOCK TABLES
, чтобы ускорить дела
(много модификаций внутри одиночной блокировки выполняются намного быстрее,
чем модификации без блокировок). Разделение данных к различным таблицам также
будет весьма полезно.
Если Вы получаете проблемы быстродействия с блокировками таблицы в MySQL,
Вы можете решить их, если преобразовать некоторых из Ваших таблиц к типу
BDB
. Подробности в разделе "7.5
Таблицы BDB или Berkeley_DB".
Раздел оптимизации в данном руководстве охватывает много различных аспектов того, как правильно настроить прикладную программу. Подробности в разделе "5.2.11 Другие советы по оптимизации".
Я пробовал использовать пакет потоков RTS с MySQL, но застрял на следующих проблемах:
Они используют старую версию POSIX calls, и очень утомительно делать обертки для всех функций. Я склонен думать, что было бы проще изменить библиотеки на самую новую POSIX-спецификацию.
Некоторые обертки уже написаны. Подробности в файле mysys/my_pthread.c.
По крайней мере следующее должно быть изменено:
pthread_get_specific
должен использовать один параметр.
sigwait
должен брать два параметра. Много функций (по крайней
мере pthread_cond_wait
, pthread_cond_timedwait
)
должны возвратить код ошибки. Сейчас они возвращают -1 и устанавливают
errno
.
Другая проблема: потоки уровня пользователя используют сигнал
ALRM
, а это прерывает много функций (read
,
write
, open
...). MySQL должен делать повторение на
прерывании, но попробуй-ка их все отследи!
Самая большая нерешенная проблема:
Чтобы получать тревоги уровня потока, я изменил
mysys/thr_alarm.c, чтобы ждать между тревогами с помощью
pthread_cond_timedwait()
, но это прерывается с ошибкой
EINTR
. Я пробовал отлаживать библиотеки потоков относительно
того, почему это случается, но не смог найти простое решение.
Если кто-то хочет попробовать собрать MySQL с потоками RTS, я предлагаю:
-DHAVE_rts_threads
.
thr_alarm
.
thr_alarm
. Если это выполняется без сообщений
``warning'', ``error'' и им подобных, Вы на правильном пути. Даже имеется
одно успешное выполнение на Solaris:
Main thread: 1 Thread 0 (5) started Thread: 5 Waiting process_alarm Thread 1 (6) started Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 1 (1) sec Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 2 (2) sec Thread: 6 Simulation of no alarm needed Thread: 6 Slept for 0 (3) sec Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 4 (4) sec Thread: 6 Waiting process_alarm thread_alarm Thread: 5 Slept for 10 (10) sec Thread: 5 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 5 (5) sec Thread: 6 Waiting process_alarm process_alarm ... thread_alarm Thread: 5 Slept for 0 (1) sec end
MySQL очень зависит от используемого пакета потоков. Так при выборе хорошей платформы для MySQL, этот пакет очень важен.
Имеются по крайней мере три типа пакетов потоков:
ps
может показывать
различные потоки. Если один поток аварийно завершен, то накроется весь
процесс. Большинство системных вызовов безопасны с точки зрения потоков.
Solaris, HP-UX, AIX и OSF1 имеют ядерные потоки.В некоторых ядрах систем потоки реализуются, интегрируя потоки уровня пользователя в библиотеках систем. В таких случаях переключение может быть выполнено только библиотекой потоков, а ядро реально потоков не знает.
Эта глава описывает некоторые общие проблемы и сообщения об ошибках, с которыми пользователи столкнулись. Вы узнаете, как точно определить происходящее, и что делать, чтобы решить возникшую проблему. Вы также найдете здесь соответствующие решения для некоторых общих проблем.
Когда Вы сталкиваетесь с проблемами, первое, что Вы должны сделать, это однозначно выяснить, которая программа или часть оборудования вызывает данные проблемы.
kbd_mode -a
.
top
, ps
, taskmanager
или некоторую
подобную программу, чтобы установить, которая программа занимает весь CPU
или блокирует машину.
top
, df
или подобной
программы, не исчерпана ли память, место на диске или иной критический ресурс.
Если после того, как Вы исследовали все другие возможности и заключили, что проблема заключается в клиенте или сервере MySQL, самое время сделать отчет об ошибке для списка рассылки или группы поддержки. В отчете ошибки попробуйте дать очень детальное описание того, как система ведет себя, и что с ней случается. Вы должны также установить, почему Вы думаете, что это вызвано именно MySQL. Учтите все ситуации в этой главе. Установите любые проблемы точно, как они появляются, когда Вы исследуете вашу систему. Используйте метод "вырезать и вставить" для любого вывода, сообщений об ошибках из программ и журналов.
Если сбоит программа, всегда полезно знать следующее:
top
. Позвольте программе поработать некоторое время, она может
оценивать что-то тяжелое.
mysqld
вызывает проблемы, Вы можете сделать
mysqladmin -u root ping
или mysqladmin -u root
processlist
?
mysql
), когда Вы пробуете соединяться с сервером MySQL? Клиент
зависает? Вы получаете любой вывод из программы?При посылке отчета об ошибке Вы должны обязательно следовать правилам, описанным в этом руководстве.
Этот раздел перечисляет некоторые ошибки, с которыми пользователи часто сталкиваются. Здесь Вы найдете описания ошибок, и как решить проблему.
Access denied
Обратитесь к разделам
"4.2.5 Как работает система привилегий" и
особенно "4.2.10 Причины ошибки
Access denied
".
MySQL server has gone away
Наиболее общая причина для ошибки MySQL server has gone away
состоит в том, что у сервера кончилось время ожидания, и он закрыл
подключение. По умолчанию сервер закрывает подключение после 8 часов
отсутствия активности. Вы можете изменять срок, устанавливая переменную
wait_timeout
, когда Вы запускаете mysqld
Другая общая причина получения такой ошибки состоит в том, что Вы закрыли соединение, а теперь пробуете выполнить запрос на закрытом подключении.
Вы можете проверять, что MySQL работает, выполняя mysqladmin
version
и исследуя uptime.
Если Вы имеете скрипт, Вы только должны снова выдать запрос клиенту, чтобы сделать автоматическое переподключение.
Вы обычно можете получать следующие коды ошибки в этом случае:
CR_SERVER_GONE_ERROR | Клиент не может послать запрос на сервер. |
CR_SERVER_LOST | Клиент не получал ошибку при записи на сервер, но и не получил полный ответ (или любой ответ) на запрос. |
Вы можете также получать эти ошибки, если Вы посылаете неправильной или
слишком большой запрос серверу. Если mysqld
получает пакет,
который является слишком большим или вне правил, он считает, что что-то
пошло неправильно с клиентом и закрывает подключение. Если Вы нуждаетесь в
больших запросах (например, если Вы работаете с большими столбцами
BLOB
), Вы можете увеличить ограничение запроса, запуская
mysqld
с опцией -O max_allowed_packet=#
(по
умолчанию 1M). Память дополнительного пространства распределена по
требованию, так что mysqld
использует большее количество памяти
только, когда Вы выдаете большой запрос, или когда mysqld
должен
возвратить большую строку результатов!
Can't connect to [local] MySQL server
Клиент MySQL под ОС Unix может соединяться с сервером mysqld
двумя различными способами: Unix-сокеты, которые подключают через файл в
файловой системе (значение по умолчанию /tmp/mysqld.sock) или по
протоколу TCP/IP, который соединяется через номер порта. Unix-сокеты быстрее,
чем TCP/IP, но могут использоваться только при соединении с сервером на том
же самом компьютере. Они применяются, если Вы не определяете hostname, или
если Вы определяете специальное имя localhost
.
Под Windows Вы можете соединяться только через TCP/IP, если сервер
mysqld
запущен под Win95/Win98. Если же использована NT, Вы
можете также соединяться с именованными каналами. Имя такого именованного
канала MySQL. Если Вы не задаете hostname при соединении с сервером, клиент
сначала попробует соединяться с именованным каналом, и если это не работает,
то соединится с TCP/IP портом. Вы можете заставить использовать именованный
канал под Windows, указав точку (.
) как hostname.
Сообщение error (2002) Can't connect to ...
обычно означает,
что не имеется сервера MySQL на системе, что Вы используете неправильный файл
сокета или не тот TCP/IP порт при попытке соединиться с mysqld
.
Начните с проверки (ps
или через администратор задач под
Windows), что вообще имеется процесс, управляющий mysqld
на
Вашем сервере! Если не имеется никакого процесса mysqld
, Вы
должны его запустить. Подробности в разделе
"2.4.2
Проблемы с запуском сервера MySQL".
Если процесс mysqld
работает, Вы можете проверять сервер,
пробуя различные подключения (номер порта и имя пути сокета):
shell> mysqladmin version shell> mysqladmin variables shell> mysqladmin -h `hostname` version variables shell> mysqladmin -h `hostname` --port=3306 version shell> mysqladmin -h 'ip for your host' version shell> mysqladmin --socket=/tmp/mysql.sock version
Обратите внимание на использование апострофов вместо кавычек с командой
hostname
: они заставляют вывод hostname
(то есть,
текущий hostname) вставиться в mysqladmin
.
Имеются некоторые причины, по которым может происходить ошибка Can't
connect to local MySQL server
:
mysqld
не запущен.
mysqld
использует пакет MIT-pthreads. Подробности в разделе
"2.2.2 ОС, поддерживаемые MySQL". Однако,
все версии MIT-pthreads не поддерживают Unix-сокеты. На системе без поддержки
сокетов Вы должны всегда определять hostname явно при соединении с сервером.
Попробуйте использовать эту команду, чтобы проверить подключение:
shell> mysqladmin -h `hostname` version
mysqld
, (по
умолчанию это /tmp/mysqld.sock). Вы могли бы иметь задачу для
планировщика cron
, которая удаляет старые файлы из каталога
/tmp, и сокет вместе с ними). Вы можете всегда выполнять
mysqladmin version
и проверять, что каталог сокета в самом деле
существует. Подробности в разделе
"8.4.5 Как защитить или
сменить файл сокета MySQL /tmp/mysql.sock".
mysqld
с опцией
--socket=/path/to/socket
. Если Вы изменяете имя пути сокета для
сервера, не забудьте поставить об этом в известность клиентов. Вы можете
сделать это, обеспечивая путь к сокету как параметр клиента. Подробности в
разделе "8.4.5
Как защитить файл сокета MySQL /tmp/mysql.sock".
mysqld
(например, скриптом
mysql_zap
прежде, чем Вы сможете запустить новый сервер MySQL).
mysqld
так, чтобы он использовал каталог, к
которому Вы можете обращаться.Если Вы получаете сообщение об ошибке Can't connect to MySQL server
on some_hostname
, Вы можете попробовать следующие вещи, чтобы
выяснить, какова проблема:
telnet
your-host-name tcp-ip-port-number
с двойным нажатием
RETURN
. Если имеется сервер MySQL, слушающий на этом порте, Вы
должны получить ответ, который включает номер версии. Если Вы получаете
ошибку подобно telnet: Unable to connect to remote host: Connection
refused
, стало быть там не имеется никакого сервера. Куда он делся?
Это уже другой вопрос, ищите...
mysqld
на локальной машине и
проверить TCP/IP порт, на который mysqld
сконфигурирован
(переменная port
) с помощью mysqladmin variables
.
mysqld
не запущен с параметром
--skip-networking
.Host '...' is blocked
Если Вы получаете сообщение об ошибке:
Host 'hostname' is blocked because of many connection errors. Unblock with 'mysqladmin flush-hosts'
Это означает, что mysqld
получил много
(max_connect_errors
) запросов подключения с компьютера
hostname
, которые были прерваны в середине. После
max_connect_errors
потерпевших неудачу запросов
mysqld
считает, что что-то неправильно (подобно нападению
хакеров) и блокирует дальнейшие соединения с этой машины, пока кто-то не
выполняет команду mysqladmin flush-hosts
.
По умолчанию mysqld
блокирует компьютер после 10 ошибок
подключения. Вы можете легко корректировать это, запуская сервер так:
shell> safe_mysqld -O max_connect_errors=10000 &
Обратите внимание, что, если Вы получаете это сообщение об ошибках для
данного компьютера, Вы должны сначала проверить, что не имеется чего-нибудь
неправильного с TCP/IP подключениями. Если Ваши TCP/IP подключения не
работают, увеличение переменной max_connect_errors
не поможет!
Too many connections
Если Вы получаете ошибку Too many connections
, когда Вы
пробуете соединиться с MySQL, это означает, что уже имеется
max_connections
клиентов, работающих с сервером.
Если Вы нуждаетесь в большем количестве подключений, чем значение по
умолчанию (100), то перезапустите mysqld
с большим значением для
переменной max_connections
.
Обратите внимание, что mysqld
фактически позволяет
(max_connections
+1) подключений. Последнее подключение
зарезервировано для пользователя с привилегией process.
Не давая эту привилегию нормальным пользователям (они не должны нуждаться в
ней), администратор с этой привилегией может войти и использовать
SHOW PROCESSLIST
, чтобы выяснить то, что могло бы быть
неправильно. Подробности в разделе "4.5.5
Синтаксис команды SHOW
".
Максимальное количество подключений зависит от того, как хороша библиотека потоков на данной платформе. Linux или Solaris могут поддерживать 500-1000 одновременных подключений в зависимости от того, сколько RAM Вы имеете, и что Ваша клиентура делает.
Some non-transactional changed tables couldn't
be rolled back
Если Вы получаете ошибку Warning: Some non-transactional changed
tables couldn't be rolled back
при попытке сделать
ROLLBACK
, это означает, что некоторые из таблиц, которые Вы
использовали, не поддерживали транзакции. На эти таблицы не будет
воздействовать инструкция ROLLBACK
.
Наиболее типичный случай, когда это случается: когда Вы пробовали
создавать таблицу типа, который не поддержан Вашей версией
mysqld
. Если mysqld
не поддерживает тип таблицы
(или если тип таблицы заблокирован опцией запуска), он взамен создаст таблицу
такого типа, который больше всего подходит к тому, который Вы запросили,
вероятно, это будет MyISAM
.
Вы можете проверять тип таблицы:
SHOW TABLE STATUS LIKE 'table_name'.Подробности в разделе "4.5.5.2
SHOW TABLE STATUS
".
Вы можете проверять, какие расширения поддерживает Ваша версия
mysqld
следующей командой:
show variables like 'have_%'
. Подробности в разделе
"4.5.5.4 Синтаксис SHOW VARIABLES
".
Out of memory
Если Вы выдаете запрос и получаете нечто вроде следующей ошибки:
mysql: Out of memory at line 42, 'malloc.c' mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k) ERROR 2008: MySQL client ran out of memory
Обратите внимание, что ошибка относится к клиенту mysql
.
Причина для этой ошибки: клиент не имеет достаточно памяти, чтобы сохранить
целиком полученный результат.
Чтобы выправить проблему, сначала проверьте, что Ваш запрос правилен.
Является ли приемлемым, чтобы он возвратил так много строк? Если да, Вы
можете использовать mysql --quick
, который использует
mysql_use_result()
, чтобы получить набор результатов. Это
помещает меньшее количество нагрузки на клиента (но больше на сервер).
Packet too large
Когда клиент MySQL или сервер mysqld
получает пакет больше,
чем max_allowed_packet
байт, он выдает ошибку Packet too
large
и закрывает подключение.
Если Вы используете клиента mysql
, Вы можете определять
больший буфер, запуская клиента командой
mysql --set-variable=max_allowed_packet=8M
.
Если Вы используете другую клиентуру, которая не позволяет Вам определять
максимальный размер пакета (типа DBI
), Вы должны установить
размер пакета, когда Вы запускаете сервер. Вы используете опцию командной
строки для mysqld
, чтобы установить
max_allowed_packet
к большему размеру. Например, если Вы
ожидаете сохранять полную длину BLOB
в таблицу, Вы будете должны
запустить сервер с опцией --set-variable=max_allowed_packet=16M
.
Вы можете также получать странные проблемы с большими пакетами, если Вы
используете большие blob'ы, но не дали mysqld
доступ к
достаточной памяти, чтобы обработать запрос. Если Вы подозреваете, что дело
обстоит именно так, попробуйте добавить ulimit -d 256000
к
скрипту safe_mysqld
и перезапустить mysqld
.
Начиная с MySQL 3.23.40
Вы получаете только ошибку
Aborted connection
при запуске mysqld
с опцией
--warnings
.
Если Вы находите ошибки, подобные следующей, в Вашем файле регистрации:
010301 14:38:23 Aborted connection 854 to db: 'users' user: 'josh'
Это означает, что что-то из следующего случилось:
mysql_close()
перед
выходом.
wait_timeout
или
interactive_timeout
без того, чтобы делать любые запросы.
Когда вышеупомянутое случается, переменная сервера
Aborted_clients
будет увеличена.
Переменная сервера Aborted_connects
растет:
connect_timeout
секунд, чтобы
получить подключенный пакет.Обратите внимание, что вышеупомянутое может указывать, что кто-то пробует врываться в Вашу базу данных!
Другие причины для проблем с клиентами и прерванными подключениями.
max_allowed_packet
слишком маленький, или запросы требуют
большее количество памяти, чем Вы имеете для mysqld
.The table is full
Эта ошибка происходит в старых версиях MySQL, когда расположенная в памяти
временная таблица становится больше, чем tmp_table_size
байт.
Чтобы избежать этой проблемы, Вы можете использовать опцию -O
tmp_table_size=#
, чтобы увеличить размер временной таблицы или
использовать опцию SQL_BIG_TABLES
прежде, чем Вы
выдаете проблематичный запрос.
Вы можете также запустить mysqld
с опцией
--big-tables
. Это действует точно также, как использование для
всех запросов SQL_BIG_TABLES
.
В MySQL Version 3.23 временная таблица в памяти будет автоматически
преобразована в дисковую MyISAM
после того, как размер таблицы
станет больше, чем tmp_table_size
.
Can't create/write to file
Если для некоторых запросов Вы получаете ошибку типа:
Can't create/write to file '\\sqla3fe_0.ism'.
Это означает, что MySQL не может создать временный файл для набора
результатов в заданном временном каталоге. Для исправления запустите
mysqld
с опцией --tmpdir=path
или добавьте к файлу
опцией сервера следующее:
[mysqld] tmpdir=C:/temp
Считается, что каталог c:\temp существует.
Проверьте также код ошибки, который Вы получаете через
perror
. Причиной может быть также полный диск;
shell> perror 28 Error code 28: No space left on device
Commands out of sync
Если Вы получаете Commands out of sync; You can't run this command
now
в Вашем коде пользователя, стало быть Вы вызываете функции
пользователя в неправильном порядке!
Это может случаться, например, если Вы используете
mysql_use_result()
и пробуете выполнять новый запрос прежде, чем
Вы вызвали mysql_free_result()
. Это может также случаться, если
Вы пробуете выполнять два запроса, которые возвращают данные, без
обязательного вызова функции mysql_use_result()
или
mysql_store_result()
между ними.
Ignoring user
Если Вы получаете следующую ошибку:
Found wrong password for user: 'some_user@some_host'; Ignoring user
Это означает, что, когда mysqld
запустился или перезагрузил
таблицы привилегий, он нашел запись в таблице user
с
недопустимым паролем. В результате запись просто игнорируется системой.
Возможные причины для этой проблемы:
mysqld
со старой
таблицей user
. Вы можете проверить это, выполняя mysqlshow
mysql user
, чтобы видеть, является ли поле пароля короче, чем 16
символов. Если это так, Вы можете исправлять это дело запуском скрипта
scripts/add_long_password
.
mysqld
с опцией --old-protocol
. Модифицируйте
пользователя в таблице user
с новым паролем или перезапустите
mysqld
с опцией --old-protocol
.
user
без того, чтобы использовать функцию PASSWORD()
. Примените
mysql
, чтобы модифицировать пользователя в таблице
user
с новым паролем. Удостоверьтесь, что вызвана функция
PASSWORD()
:
mysql> update user set password=PASSWORD('your password') where user='XXX';
Table 'xxx' doesn't exist
Если Вы получаете ошибку Table 'xxx' doesn't exist
или
Can't find file: 'xxx' (errno: 2)
, это означает, что таблица с
именем xxx
не существует в текущей (актуальной) базе данных.
Обратите внимание, что MySQL использует каталоги и файлы, чтобы сохранить базы данных и таблицы, так что имена баз данных и таблиц чувствительны к регистру! В Windows это не так, но все ссылки к данной таблице внутри запроса должны использовать тот же самый регистр.
Вы можете проверить, какие таблицы Вы имеете в текущей базе данных, через
SHOW TABLES
. Подробности в разделе "
4.5.5 Синтаксис SHOW
".
Can't initialize character set xxx
Если Вы получаете ошибку подобно:
MySQL Connection Failed: Can't initialize character set xxx
Это означает одно из следующего:
--with-charset=xxx
или --with-extra-charsets=xxx
.
Все стандартные двоичные файлы MySQL компилируются с
--with-extra-character-sets=complex
, что допускает поддержку для
всех многобайтных наборов символов.
mysqld
, и файлы определения набора символов не в том месте, где
клиент ожидает находить их. В этом случае Вы должны:
--character-sets-dir=path-to-charset-dir
.
Если Вы получаете ERROR '...' not found (errno: 23)
,
Can't open file: ... (errno: 24)
или любую другую ошибку с
errno 23
или errno 24
из MySQL, это означает, что
Вы не распределили достаточно описателей файла для MySQL. Вы можете
использовать утилитку perror
, чтобы получить описание того, что
код ошибки означает:
shell> perror 23 File table overflow shell> perror 24 Too many open files shell> perror 11 Resource temporarily unavailable
Проблема здесь состоит в том, что mysqld
пробует хранить
открытыми слишком много файлов одновременно. Вы можете сообщать, чтобы
mysqld
не открывал так много файлов сразу, или увеличить число
описателей файла, доступных для mysqld
.
Чтобы сообщать, чтобы mysqld
хранил открытым меньшее
количество файлов одновременно, Вы можете сделать кэш таблицы меньшим,
используя опцию -O table_cache=32
при вызове
safe_mysqld
(значение по умолчанию 64). Уменьшение значения
max_connections
также уменьшит число открытых файлов (значение
по умолчанию: 90).
Чтобы изменять число описателей файла, доступных
mysqld
, Вы можете использовать опцию
--open-files-limit=#
при вызове safe_mysqld
или
-O open-files-limit=#
при запуске mysqld
. Самый
простой способ сделать это состоит в том, чтобы добавить опцию к Вашему
файлу опции. Если Вы имеете старую версию mysqld
, которая не
поддерживает это, Вы можете отредактировать скрипт safe_mysqld
.
Имеется прокомментированная строка ulimit -n 256
в скрипте. Вы
можете удалять символ #
, чтобы раскомментировать строку и
изменить число 256, чтобы воздействовать на число описателей файла.
ulimit
(и open-files-limit
) может увеличивать
число описателей файла, но только до ограничения, наложенного операционной
системой. Имеется также жесткое ограничение, которое может быть перекрыто
только, если Вы запускаете safe_mysqld
или mysqld
как root (только не забудьте, что Вы должны также использовать опцию
--user=..
в этом случае). Если Вы должны увеличить ограничение
OS на число описателей файла, доступных каждому процессу, консультируйтесь с
документацией для Вашей операционной системы.
Обратите внимание, что, если Вы выполняете оболочку tcsh
,
ulimit
не будет работать! tcsh
также сообщит
неправильные значения, когда Вы спросите о текущих ограничениях. В этом
случае Вы должны запустить safe_mysqld
из sh
.
Если Вы компонуете Вашу программу и получаете ошибки для невызванных
символов, которые начинаются с mysql_
, подобно следующему:
/tmp/ccFKsdP8.o: In function `main': /tmp/ccFKsdP8.o(.text+0xb): undefined reference to `mysql_init' /tmp/ccFKsdP8.o(.text+0x31): undefined reference to `mysql_real_connect' /tmp/ccFKsdP8.o(.text+0x57): undefined reference to `mysql_real_connect' /tmp/ccFKsdP8.o(.text+0x69): undefined reference to `mysql_error' /tmp/ccFKsdP8.o(.text+0x9a): undefined reference to `mysql_close'
Вы должны быть способны решить это, добавляя
-Lpath-to-the-mysql-library -lmysqlclient
В САМОМ КОНЦЕ
строки для компоновщика.
Если Вы получаете ошибки undefined reference
для функций
uncompress
или compress
, добавьте -lz
В САМОМ КОНЦЕ строки для компоновщика.
Если Вы получаете ошибки undefined reference
для функций,
которые должны существовать в Вашей системе, подобно connect
,
проверьте man-страницу для рассматриваемой функции, чтобы выяснить, какую
библиотеку Вы должны добавить.
Если Вы получаете ошибки undefined reference
для функций,
которые не существуют в Вашей системе, подобно следующему:
mf_format.o(.text+0x201): undefined reference to `__lxstat'
Это обычно означает, что библиотека компилируется на системе, которая не на 100%, совместима с Вашей. В этом случае Вы должны загрузить последний исходник MySQL и откомпилировать библиотеку непосредственно.
Если Вы пробуете выполнять программу и получаете ошибки для невызванных
символов, которые начинаются с mysql_
, или о том, что библиотека
mysqlclient
не может быть найдена, это означает, что Ваша
система не может найти общую библиотеку libmysqlclient.so
.
libmysqlclient.so
, к системной переменной
LD_LIBRARY_PATH
.
libmysqlclient.so
, к системной переменной
LD_LIBRARY
.
libmysqlclient.so
в место, где система ищет общие
библиотеки, например, /lib, и модифицируйте общедоступную
библиотечную информацию, выполняя ldconfig
.Другой способ решать эту проблему состоит в том, чтобы скомпоновать Вашу
программу статически с опцией -static
или удалить динамические
библиотеки MySQL перед компоновкой Вашего кода. Во втором случае Вы должны
убедиться, что никакие другие программы не используют динамические библиотеки!
MySQL-сервер mysqld
может быть запущен и выполняться любым
пользователем. Чтобы mysqld
работал как Unix-пользователь
user_name
, Вы должны сделать следующие шаги:
mysqladmin shutdown
).
user_name
имел права на чтение и запись:
shell> chown -R user_name /path/to/mysql/datadirЕсли каталоги или файлы внутри каталога данных MySQL представляют собой символические ссылки, Вы будете также должны следовать за теми связями и изменять каталоги и файлы, на которые они указывают. Увы,
chown -R
не может следовать за ссылками для Вас.
user_name
или, если Вы
используете MySQL Version 3.22 или позже, как Unix-пользователь
root
с опцией --user=user_name
.
mysqld
переключится на Unix-пользователя user_name
перед принятием любых подключений.
user
, которая определяет имя
пользователя, к группе [mysqld]
файла /etc/my.cnf (или
my.cnf) в каталоге данных сервера. Например:
[mysqld] user=user_name
Обратите внимание, что доступ к MySQL как root
указанием
-u root
в командной строке, не имеет никакого отношения
к запуску MySQL как root
. Права доступа и имена пользователей
MySQL полностью независимы от имен в Unix. Единственное подключение с именем
пользователя Unix происходит, если Вы не указали опцию -u
, когда
Вы вызываете программу пользователя. Клиент пробует подключиться, используя
Ваше Unix-имя входа в систему как имя пользователя MySQL.
Если Вы имеете проблемы с правами доступа к файлам, например, если
mysql
выдает такое сообщение об ошибке, когда создаете таблицу:
ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13)
То системная переменная
UMASK
может быть установлена неправильно, когда запускается
mysqld
. Значение по умолчанию для umask: 0660
.
Вы можете изменять это поведение, запуская safe_mysqld
так:
shell> UMASK=384 # = 600 in octal shell> export UMASK shell> /path/to/safe_mysqld &
По умолчанию MySQL создаст
базу данных и каталоги RAID
с правами доступа 0700. Вы можете
изменять это поведение, устанавливая переменную UMASK_DIR
.
Если Вы устанавливаете ее, новые каталоги будут созданы с объединением
UMASK
и UMASK_DIR
. Например, если Вы хотите давать
группе доступ ко всем новым каталогам, Вы можете сделать:
shell> UMASK_DIR=504 # = 770 в аосьмеричном формате. shell> export UMASK_DIR shell> /path/to/safe_mysqld &
В MySQL Version 3.23.25 и выше MySQL считает, что значения
UMASK
и UMASK_DIR
заданы в восьмеричном формате,
если они начинаются с ноля.
Все версии MySQL проверены на многих платформах прежде, чем они выпущены. Это не означает, что не имеется любых ошибок в MySQL, но это означает, что их там очень мало.
Сначала Вы должны пробовать выяснять, состоит ли проблема в том, что
mysqld
падает, или ее корень надо искать на клиенте. Вы можете
проверять время работы сервера mysqld
командой mysqladmin
version
. Если mysqld
свалился, Вы можете находить причину
этого в файле mysql-data-directory/hostname.err.
Много сбоев MySQL вызваны разрушенным индексом или файлами данных. MySQL
модифицирует данные относительно диска через системный вызов
write()
после каждой инструкции SQL, но прежде, чем пользователю
сообщают относительно результата. Это не так, если Вы работаете с опцией
delayed_key_writes
, когда только данные будут записаны. Это
означает, что данные в безопасности, даже если сбоит mysqld
,
если ОС гарантируют, что данные будут сброшены из кэша на диск. Вы можете
заставить MySQL сбрасывать кэш принудительно после каждой команды SQL,
запуская mysqld
с опцией --flush
.
Вышеупомянутое означает, что обычно Вы не должны получить разрушенные таблицы и файлы, если:
mysqld
в середине модификации.
mysqld
, которая разрушила его
в середине модификации.
mysqld
на тех же
самых данных в системе, которая не поддерживает хорошие блокировки файловой
системы (обычно обрабатываемые сервером lockd
), или была указана
опция --skip-locking
при запуске сервера.
mysqld
запутался.
ALTER TABLE
на
восстановленной копии таблицы.Поскольку очень трудно узнать, почему что-то терпит крах, сначала попробуйте проверить следующее:
mysqld
с помощью mysqladmin
shutdown
, запустите myisamchk --silent --force */*.MYI
на
всех таблицах и перезапустите сервер mysqld
. Это гарантирует,
что Вы запустились с чистого состояния.
mysqld --log
и попробуйте определить из
информации в файле регистрации, уничтожает или нет некоторый специфический
запрос сервер. Приблизительно 95% всех ошибок связаны со специфическим
запросом! Обычно это один из последних запросов в журнале. Если Вы можете
повторить процесс уничтожения MySQL одним из запросов даже, когда Вы проверили
все таблицы перед выполнением запроса, то ошибка локализована. Готовьте отчет
об ошибке. Подробности в разделе "1.4.1 Как
сообщать об ошибках и проблемах".
fork_test.pl
и
fork2_test.pl
.
--with-debug
или с
--with-debug=full
для скрипта configure
, чтобы
конфигурировать и затем перетранслировать пакет. Подробности в разделе
"6.1 Отладка сервера MySQL".
--skip-locking
для mysqld
.
На некоторых системах администратор блокировок lockd
не работает
правильно. Опция --skip-locking
сообщает, чтобы
mysqld
не использовал внешнюю блокировку. Это означает, что Вы
не сможете выполнять несколько серверов mysqld
на тех же самых
данных, и что Вы должны быть внимательны, если Вы используете
myisamchk
, но может быть поучительно опробовать опцию как тест.
mysqladmin -u root processlist
, когда
mysqld
работает, но не отвечает? Иногда mysqld
не
завис даже при том, что Вы могли бы думать именно так. Проблема может
состоять в том, что все подключения находятся в использовании, или может
иметься некоторая внутренняя проблема блокировки. Вызов mysqladmin
processlist
обычно будет способен делать подключение даже в этих
случаях и может обеспечивать полезную информацию относительно текущего числа
подключений и их состояния.
mysqladmin -i 5 status
или
mysqladmin -i 5 -r status
, чтобы произвести статистику в то
время, как Вы выполняете другие Ваши запросы.
mysqld
из gdb
(или в другом
отладчике. Подробности в разделе "
6.1.3 Отладка mysqld под gdb".
mysqld
развалился под gdb:
backtrace info local up info local up info localС gdb Вы можете также исследовать, которые потоки существуют, командой
info threads
, и переключаться на нужный поток командой
thread #
, где #
задает идентификатор потока.BLOB/TEXT
(только VARCHAR
),
Вы можете пробовать изменять все VARCHAR
на CHAR
с
помощью команды ALTER TABLE
. Это вынудит MySQL использовать
строки фиксированных размеров. Они берут небольшое дополнительное
пространство, но намного более терпимы к искажению! Текущий динамический код
строки был в использовании в MySQL AB по крайней мере 3 года без всяких
проблем, но строки динамической длины вообще более склонны к ошибкам, так что
посмотрите, что получится.Если Вы забыли пароль пользователя root
для MySQL, Вы можете
восстанавливать его следующей процедурой:
mysqld
отправкой ему команды
kill
(но не kill -9
!). Идентификатор процесса будет
сохранен в .pid
-файле, который обычно хранится в каталоге для
баз данных MySQL:
kill `cat /mysql-data-directory/hostname.pid`Вы должны быть Unix-пользователем
root
или тем пользователем, от
имени которого выполняется сервер.
mysqld
с опцией
--skip-grant-tables
.
mysqld
командой mysql -h hostname
mysql
и смените пароль командой GRANT
. Подробности в
разделе "4.3.1 Синтаксис GRANT
и
REVOKE
". Вы можете также делать это с помощью команды
mysqladmin -h hostname -u user password new_password
.
mysqladmin -h hostname
flush-privileges
или командой SQL FLUSH PRIVILEGES
.Обратите внимание, что после того, как Вы запустили mysqld
с
опцией --skip-grant-tables
, любое использование команды
GRANT
даст Вам ошибку Unknown command
, пока Вы не
выполните FLUSH PRIVILEGES
.
Когда диск полностью заполнится, MySQL делает следующее:
Чтобы облегчить проблему, Вы можете предпринять следующие действия:
mysqladmin kill
потоку. Он
будет прерван, когда в следующий раз проверит диск (через минуту).
Исключительные ситуации: Вы используете REPAIR
или
OPTIMIZE
, индексы созданы в пакете после LOAD DATA
INFILE
, или выполнена инструкция ALTER TABLE
.
Все вышеприведенные команды могут использовать большие временные файлы,
которые остались после них на диске, что вызовет большие проблемы для
остальной части системы. Если MySQL переполняет диск при выполнении любой из
вышеупомянутых операций, он удалит большие временные файлы и отметит таблицу
как поврежденную (исключение: ALTER TABLE
, в этом случае старая
таблица будет оставлена неизменной).
MySQL использует значение системной переменной TMPDIR
как имя
пути каталога, чтобы сохранить временные файлы. Если Вы не имеете
TMPDIR
, MySQL использует системное значение по умолчанию,
которое является обычно /tmp или /usr/tmp. Если файловая
система, содержащая Ваш временный каталог слишком маленькая, Вы должны
отредактировать скрипт safe_mysqld
, чтобы установить
TMPDIR
так, чтобы указать на каталог в файловой системе, где Вы
имеете достаточно места. Вы можете также устанавливать временный каталог,
используя опцию --tmpdir
при вызове mysqld
.
MySQL создает все временные файлы как скрытые. Это гарантирует, что
временные файлы будут удалены, если mysqld
завершен. Недостаток
использования скрытых файлов в том, что Вы не будете видеть большой временный
файл, заполняющий файловую систему, в которой размещен временный каталог.
При сортировке (ORDER BY
или GROUP BY
) MySQL
обычно использует один или два временных файла. Максимальное дисковое
пространство, необходимое для сортировки:
(Длина сортируемых данных+sizeof(database pointer))* число совпадающих строк*2
Здесь sizeof(database pointer)
обычно 4, но может расти в
будущем для действительно больших таблиц.
Для некоторого запроса SELECT
MySQL также создает временные
SQL-таблицы. Они не скрыты и имеют имена формы SQL_*.
ALTER TABLE
создает временную таблицу в том же самом
каталоге, где находится и первоначальная таблица.
Если Вы имеете проблемы с тем фактом, что любой может удалять сокет
MySQL /tmp/mysql.sock, Вы можете, на большинстве версий Unix,
защитить Вашу файловую систему /tmp, устанавливая липкий бит на ней.
Зайдите в систему как root
и скомандуйте:
shell> chmod +t /tmp
Это защитит Вашу файловую систему /tmp так, чтобы файлы могли
быть удалены только их владельцами или суперпользователем (root
).
Вы можете проверять, установлен ли липкий бит, выполняя
ls -ld /tmp
. Если последний бит прав доступа равен
t
, липкий бит установлен.
Вы можете изменять место, где MySQL помещают файл сокета, так:
/etc/my.cnf
:
[client] socket=path-for-socket-file [mysqld] socket=path-for-socket-file
safe_mysqld
и для
большинства клиентов опцией --socket=path-for-socket-file
.
MYSQL_UNIX_PORT
.
--with-unix-socket-path=path-for-socket-file
для скрипта
configure
. Подробности в разделе
"2.3.3
Типичные опции для configure
".Вы можете проверять, что сокет работает, с помощью команды:
shell> mysqladmin --socket=/path/to/socket version
Если Вы имеете проблему с SELECT NOW()
, возвращающим значения
в GMT, а не по Вашему местному времени, Вы должны установить системную
переменную TZ
к Вашему текущему часовому поясу. Это должно быть
выполнено для среды, в которой выполняется сервер, например, в скрипте
safe_mysqld
или в mysql.server
.
По умолчанию поиск в MySQL нечувствителен к регистру (хотя имеются
некоторые наборы символов, которые всегда чувствительны, например,
czech
). Это означает, что, если Вы ищете col_name LIKE
'a%'
, Вы получите все значения столбца, которые начинаются с
A
или a
. Если Вы хотите сделать этот поиск с учетом
регистра, используйте нечто подобное INSTR(col_name, "A")=1
,
чтобы проверить префикс. Или используйте STRCMP(col_name,"A")=0
,
если значение столбца было точно "A"
.
Простые операции сравнения (>=, >, =, < ,<=
,
сортировка и группировка) основаны на значении сорта каждого символа. Символы
с тем же самым значением сорта обрабатываются как тот же самый символ.
В старых версиях MySQL LIKE
выполнялся по значениям,
приведенным к верхнему регистру. В более новых версиях MySQL
LIKE
работает точно так же, как другие операторы сравнения.
Если Вы хотите, чтобы столбец всегда обработался в режиме чувствительности
к регистру, объявите его как BINARY
.
Если Вы используете китайские данные в так называемом кодировании big5, Вы
должны сделать все символьные столбцы BINARY
. Это работает
потому, что порядок сортировки символов кодирования big5 основан на
порядке ASCII кодов.
DATE
Формат значения DATE
всегда YYYY-MM-DD
. Согласно
ANSI SQL, никакой другой формат не позволяется. Вы должны использовать этот
формат в выражениях UPDATE
и в предложении WHERE инструкций
SELECT
. Например:
mysql> SELECT * FROM tbl_name WHERE date >= '1997-05-05';
Как дополнительное удобство MySQL автоматически преобразовывает дату в
число, если дата используется в числовом контексте (и наоборот). Также
достаточно интеллектуально обрабатывается ослабленная форма строки при
модифицировании и в предложении WHERE
, которое сравнивает дату
со столбцом TIMESTAMP
, DATE
или
DATETIME
. Ослабленная форма означает, что любой символ
пунктуации может использоваться как разделитель между частями. Например,
1998-08-15
и 1998#08#15
являются эквивалентными.
MySQL может также преобразовывать строку не содержащую никаких разделителей
(типа 19980815
), если она имеет смысл как дата.
Специальная дата 0000-00-00
может быть сохранена и получена
как 0000-00-00
. При использовании даты 0000-00-00
через MyODBC, это будет автоматически преобразовано в
NULL
в MyODBC Version 2.50.12 и выше потому,
что ODBC не может обрабатывать этот вид даты.
Потому, что MySQL выполняет преобразования, описанные выше, следующие инструкции всегда работают:
mysql> INSERT INTO tbl_name (idate) VALUES (19970505); mysql> INSERT INTO tbl_name (idate) VALUES ('19970505'); mysql> INSERT INTO tbl_name (idate) VALUES ('97-05-05'); mysql> INSERT INTO tbl_name (idate) VALUES ('1997.05.05'); mysql> INSERT INTO tbl_name (idate) VALUES ('1997 05 05'); mysql> INSERT INTO tbl_name (idate) VALUES ('0000-00-00'); mysql> SELECT idate FROM tbl_name WHERE idate >= '1997-05-05'; mysql> SELECT idate FROM tbl_name WHERE idate >= 19970505; mysql> SELECT mod(idate,100) FROM tbl_name WHERE idate >= 19970505; mysql> SELECT idate FROM tbl_name WHERE idate >= '19970505';
Однако, следующее работать не будет:
mysql> SELECT idate FROM tbl_name WHERE STRCMP(idate,'19970505')=0;
STRCMP()
представляет собой строковую функцию, так что это
преобразовывает idate
в строку и выполняет сравнение строк. Но
она не конвертирует 19970505
в дату и не сравнивает даты.
Обратите внимание, что MySQL не делает никакой проверки, является или нет
дата правильной. Если Вы сохраняете неправильную дату, типа
1998-2-31
, неправильная дата будет сохранена. Если дата не может
быть преобразована в любое приемлемое значение, 0
будет сохранен
в поле DATE
. Это главным образом проблема быстродействия.
NULL
Концепция значения NULL
представляет собой общий источник
беспорядка для новичков в SQL, которые часто думают, что NULL
та же самая вещь, что и пустая строка (''
). Дело обстоит не так!
Например, следующие инструкции полностью различны:
mysql> INSERT INTO my_table (phone) VALUES (NULL); mysql> INSERT INTO my_table (phone) VALUES ("");
Обе инструкции вставляют значение в столбец phone
, но первые
вставят значение NULL
, а вторая вставляет пустую строку.
Значение первой может быть расценено как "номер телефона неизвестен", а
значение второй как "не имеет никакого телефона". Есть разница?
В SQL значение NULL
всегда неправильно в сравнении с любым
другим значением. Выражение, которое содержит NULL
, всегда
производит значение NULL
, если иное не обозначено в документации
для операторов и функций, включаемых в выражение. Все столбцы в следующем
примере возвращают именно NULL
:
mysql> SELECT NULL,1+NULL,CONCAT('Invisible',NULL);
Если Вы хотите искать значения столбца, которые являются
NULL
, Вы не можете использовать тест =NULL
.
Следующая инструкция не возвращает никаких строк потому, что
expr=NULL
всегда равно FALSE для любого выражения:
mysql> SELECT * FROM my_table WHERE phone = NULL;
Чтобы искать значения NULL
, Вы должны использовать тест
IS NULL
. Следующее показывает, как найти номер телефона
NULL
и пустой номер телефона:
mysql> SELECT * FROM my_table WHERE phone IS NULL; mysql> SELECT * FROM my_table WHERE phone = "";
В MySQL, как и во многих других SQL-серверах, Вы не можете индексировать
столбцы, которые могут иметь значения NULL
. Вы должны объявить
столбцы для индекса как NOT NULL
. Наоборот, Вы не можете
вставлять NULL
в индексированный столбец.
При чтении данных через LOAD DATA INFILE
, пустые столбцы
модифицируются с ''
. Если Вы хотите иметь в столбце значение
NULL
, Вы должны использовать \N
в текстовом файле.
Литеральное слово NULL
может также использоваться.
При использовании ORDER BY
значения NULL
будут
представлены первыми. Если Вы сортируете в порядке по убыванию, используя
DESC
, значения NULL
, понятно, окажутся в хвосте.
При использовании GROUP BY
, все значения NULL
будут
расценены как равные.
Чтобы помочь СУБД с обработкой NULL
, Вы можете использовать
операторы IS NULL
и IS NOT NULL
, а также функцию
IFNULL()
. Производительность улучшится.
Для некоторых типов столбцов значения NULL
обработаны особо. Если Вы вставляете NULL
в первый столбец типа
TIMESTAMP
в таблице, реально будут вставлены текущая дата и
время. Если Вы вставляете NULL
в столбец с поддержкой
AUTO_INCREMENT
, вставится следующее число в последовательности.
alias
Вы можете использовать псевдоним, чтобы обратиться к столбцу в
GROUP BY
, ORDER BY
или в части HAVING
.
Псевдонимы могут также использоваться, чтобы дать столбцам лучшие имена:
SELECT SQRT(a*b) as rt FROM table_name GROUP BY rt HAVING rt > 0; SELECT id,COUNT(*) AS cnt FROM table_name GROUP BY id HAVING cnt > 0; SELECT id AS "Customer identity" FROM table_name;
Обратите внимание, что ANSI SQL не позволяет Вам обращаться к псевдониму в
предложении WHERE
. Это потому, что, когда код WHERE
выполнен, значение столбца не может быть определено. Например, следующий
запрос строго запрещен:
SELECT id,COUNT(*) AS cnt FROM table_name WHERE cnt > 0 GROUP BY id;
Инструкция WHERE
выполнена, чтобы определить, которые строки
должны быть включены в часть GROUP BY
в то время, как
HAVING
используется, чтобы решить, которые строки из набора
результатов должны использоваться.
Поскольку MySQL не поддерживает подвыборы или использование больше, чем
одной таблицы в инструкции DELETE
, Вы должны использовать
следующий подход, чтобы удалить строки из двух связанных таблиц:
SELECT
строки, основываясь на некотором условии
WHERE
в основной таблице.
DELETE
строки в основной таблице, основываясь на том
же самом условии.
DELETE FROM связанная_таблица WHERE связанные_столбцы
IN (выбранные_строки)
.Если общее количество символов в запросе со связанными столбцами
(related_column
) больше, чем 1048576 (значение по умолчанию
для max_allowed_packet
), Вы должны расчленить его на меньшие
части и выполнить много инструкций DELETE
. Вы, вероятно,
достигнете пика производительности при удалении 100-1000
related_column
на запрос, если related_column
является индексом. В противном случае быстродействие независимо от числа
параметров в предложении IN
.
Если Вы имеете сложный запрос, который имеет много таблиц, а он не возвращает никаких строк, Вы должны использовать следующую процедуру, чтобы выяснить, что неправильно с Вашим запросом:
EXPLAIN
и выправьте его, если
Вы можете найти что-то такое, что является очевидно неправильным. Подробности
в разделе "5.2.1 Синтаксис EXPLAIN
(получение информации о SELECT
)".
WHERE
.
LIMIT 10
.
SELECT
для столбца, который должен был
соответствовать в таблице, которая была последней удалена из запроса.
FLOAT
или DOUBLE
с
числовыми столбцами, которые имеют десятичные числа, Вы не можете
использовать =
. Эта проблема общая в большинстве компьютерных
языков потому, что значения с плавающей запятой не точные значения:
mysql> SELECT * FROM table_name WHERE float_column=3.5; -> mysql> SELECT * FROM table_name WHERE float_column between 3.45 and 3.55;В большинстве случаев замена
FLOAT
на DOUBLE
исправит это дело.
mysql test <
query.sql
, который показывает Ваши проблемы. Вы можете создавать файл
теста с помощью mysqldump --quick database tables >
query.sql
. Откройте файл в редакторе, удалите некоторые строки и
добавьте Вашу инструкцию выбора в конце файла. Проверьте, что Вы все еще
имеете Вашу проблему:
shell> mysqladmin create test2 shell> mysql test2 < query.sqlОтправьте файл теста, используя
mysqlbug
на
mysql@lists.mysql.com.ALTER TABLE
ALTER TABLE
изменяет таблицу на текущий набор символов. Если
Вы в течение ALTER TABLE
получаете ошибку дублирования ключа, то
причиной является то, что новые наборы символов отображают разные ключи к
тому же самому значению, или что таблица разрушена, тогда Вы должны выполнить
REPAIR TABLE
на таблице.
Если ALTER TABLE
падает с ошибкой подобно этой:
Error on rename of './database/name.frm' to './database/B-8.frm' (Errcode: 17)
Проблема может состоять в том, что MySQL потерпел крах в предыдущем
ALTER TABLE
, и имеется старая таблица с именем A-что-то
или B-что-то. В этом случае идите в каталог данных MySQL, и удалите
там все файлы, которые имеют имена, начинающиеся с A-
или
B-
. Вы можете перемещать их в другое место вместо того, чтобы
удалить их сразу.
ALTER TABLE
работает следующим образом:
Если что-то идет неправильно с операцией переименования, MySQL пробует отменить изменения. Если что-то идет совсем уж неправильно (этого не должно случиться, конечно), MySQL может оставить старую таблицу как B-xxx, поскольку простое переименование на уровне системы должно вернуть Ваши данные обратно в целости и сохранности.
Вы должны всегда определять порядок, в котором Вы желаете получить данные:
SELECT col_name1, col_name2, col_name3 FROM tbl_name;
Возвратит столбцы в порядке col_name1
, col_name2
,
col_name3
в то время, как:
SELECT col_name1, col_name3, col_name2 FROM tbl_name;
Возвратит столбцы в порядке col_name1
,
col_name3
, col_name2
.
Вы не должны в прикладной программе использовать
SELECT *
и получать столбцы, основываясь на их позиции потому,
что порядок, в котором столбцы возвращены, НЕЛЬЗЯ
ГАРАНТИРОВАТЬ через какое-то время. Простое изменение Вашей базы
данных может заставить Вашу прикладную программу развалиться полностью.
Если по какой-то причине Вы все же хотите изменять порядок столбцов, Вы можете сделать это следующим образом:
INSERT INTO new_table SELECT fields-in-new_table-order
FROM old_table
.
old_table
.
ALTER TABLE new_table RENAME old_table
.Следующее представляет собой список всех ограничений, действительных для
временных таблиц (TEMPORARY TABLES
).
HEAP
,
ISAM
или MyISAM
.
select * from temporary_table, temporary_table as t2;Это планируется исправить в версии 4.0.
RENAME
для таблиц
TEMPORARY
. Обратите внимание, что ALTER TABLE org_name
RENAME new_name
тем не менее работает вполне корректно! Это
планируется исправить в версии 4.0.Вы нуждаетесь в следующих инструментальных средствах, чтобы установить двоичный дистрибутив MySQL:
gunzip
, чтобы его распаковать.
tar
. GNU tar
работает. Sun
tar
, как известно, имеет проблемы.Альтернативный метод установки под Linux состоит в том, чтобы использовать пакет RPM (RedHat Package Manager). Подробности в разделе "2.1.1 Установка MySQL на Linux".
Если Вы сталкиваетесь с проблемами, ПОЖАЛУЙСТА, ВСЕГДА ИСПОЛЬЗУЙТЕ
скрипт mysqlbug
при регистрации вопросов в рассылке
mysql@lists.mysql.com. Даже если
проблема не является ошибкой, mysqlbug
соберет информацию
системы, которая поможет другим решить Вашу проблему. Не используя
mysqlbug
, Вы уменьшаете вероятность получения решения для Вашей
проблемы! Вы найдете mysqlbug
в каталоге bin после
того, как распакуете дистрибутив.
Базисные команды, которые Вы должны выполнить, чтобы установить и использовать двоичный дистрибутив MySQL:
shell> groupadd mysql shell> useradd -g mysql mysql shell> cd /usr/local shell> gunzip < /path/to/mysql-VERSION-OS.tar.gz | tar xvf - shell> ln -s mysql-VERSION-OS mysql shell> cd mysql shell> scripts/mysql_install_db shell> chown -R root /usr/local/mysql shell> chown -R mysql /usr/local/mysql/data shell> chgrp -R mysql /usr/local/mysql shell> chown -R root /usr/local/mysql/bin shell> bin/safe_mysqld --user=mysql &
Вы можете добавлять новых пользователей, используя скрипт
bin/mysql_setpermission
, если Вы устанавливаете Perl-модули
DBI
и Msql-Mysql-modules
.
Чтобы установить двоичный дистрибутив, следуйте приведенным ниже подробным инструкциям, потом перейдите к разделу "2.4 Послеустановочная настройка и тестирование" для завершения установки и тестирования:
root
.
tar
и
имеют имена подобно mysql-VERSION-OS.tar.gz, где
VERSION
представляет собой код версии (например,
3.21.15
), а OS
указывает тип операционной системы,
для которой дистрибутив предназначен (например,
pc-linux-gnu-i586
).
-max
, это
означает, что он имеет поддержку транзакционно-безопасных таблиц и других
расширенных свойств. Обратите внимание, что все двоичные коды сформированы из
того же самого исходного текста.
mysqld
:
shell> groupadd mysql shell> useradd -g mysql mysqlЭти команды добавляют группу и пользователя
mysql
. Синтаксис для
useradd
и groupadd
может немного отличаться в
различных версиях Unix. Они также могут быть названы adduser
и
addgroup
. Вообще-то необязательно называть пользователя и
группу именно mysql
.
shell> cd /usr/local
shell> gunzip < /path/to/mysql-VERSION-OS.tar.gz|tar xvf - shell> ln -s mysql-VERSION-OS mysqlПервая команда создает каталог с именем mysql-VERSION-OS. Вторая команда сделает символическую связь с этим каталогом. Это позволяет Вам обращаться к каталогу установки легче, как к /usr/local/mysql.
shell> cd mysqlВы найдете несколько файлов и подкаталогов в каталоге
mysql
.
Наиболее важные для целей установки
подкаталоги: bin и scripts.
PATH
так,
чтобы Ваша оболочка нашла программы MySQL правильно.
mysql_install_db
, используемый,
чтобы инициализировать базу данных mysql
, содержащую таблицы
предоставления привилегий, которые сохраняют разрешения доступа сервера.mysqlaccess
и иметь MySQL в
некотором ненормативном месте, Вы должны изменить расположение, где
mysqlaccess
ожидает найти клиента mysql
. Подправьте
скрипт bin/mysqlaccess. Ищите примерно такую строку:
$MYSQL='/usr/local/bin/mysql'; # path to mysql executableИзмените путь так, чтобы отразить расположение, где
mysql
фактически сохранен на Вашей системе. Если Вы не сделаете этого, Вы получите
ошибку Broken pipe
, когда выполняете mysqlaccess
.
shell> scripts/mysql_install_dbОбратите внимание, что версии MySQL до Version 3.22.10 запускали сервер MySQL, когда Вы выполняли скрипт
mysql_install_db
. Это больше
уже не так!
root
, а права владения каталогом данных тому пользователю, от
имени которого будет запускаться mysqld
:
shell> chown -R root /usr/local/mysql shell> chown -R mysql /usr/local/mysql/data shell> chgrp -R mysql /usr/local/mysqlПервая команда изменяет атрибут владельца файла (
owner
) на
root
, вторая меняет атрибут владельца (owner
)
каталога данных на mysql
, и, наконец, третья меняет атрибут
группы (group
) на группу mysql
.
support-files/mysql.server
туда, где Ваша система имеет файлы запуска. Большее количество информации
может быть найдено в самом скрипте support-files/mysql.server
.
После того, как все было распаковано и установлено, Вы должны инициализировать и проверить дистрибутив.
Вы можете запустить сервер MySQL следующей командой:
shell> bin/safe_mysqld --user=mysql &
Эта глава описывает, как получить и установить MySQL:
Рекомендуемый способ установки MySQL на Linux: используя файл RPM. MySQL
RPM в настоящее время формируются на системе RedHat Version 6.2, но должны
работать и на других версиях Linux, которые поддерживают rpm
и
используют библиотеку glibc
.
Если Вы имеете проблемы с файлом RPM, например, если Вы получаете ошибку
``Sorry, the host 'xxxx' could not be looked up
'', почитайте
раздел "2.6.1.1 Замечания по Linux
для двоичного дистрибутива".
RPM-файлы, которые Вам понадобятся:
MySQL-VERSION.i386.rpm
Сервер MySQL. Вы будете нуждаться
в нем, если Вы не хотите соединяться с сервером MySQL на другой машине.
MySQL-client-VERSION.i386.rpm
Стандартный клиент MySQL. Вы,
вероятней всего, всегда будете устанавливать этот пакет.
MySQL-bench-VERSION.i386.rpm
Тесты и бенчмарки. Требуют
RPM-пакета msql-mysql-modules и поддержки языка Perl.
MySQL-devel-VERSION.i386.rpm
Библиотеки и включаемые файлы
заголовков необходимые, если Вы хотите компилировать другую MySQL клиентуру,
типа модулей Perl.
MySQL-VERSION.src.rpm
Исходные тексты для всех приведенных
выше пакетов. Это может также использоваться, чтобы пробовать формировать
RPM-пакеты для других архитектур (например, для Alpha или SPARC).Чтобы увидеть все файлы в пакете RPM, выполните:
shell> rpm -qpl MySQL-VERSION.i386.rpm
Чтобы выполнить стандартную минимальную установку, выполните:
shell> rpm -i MySQL-VERSION.i386.rpm MySQL-client-VERSION.i386.rpm
Чтобы установить только клиентский пакет, выполните:
shell> rpm -i MySQL-client-VERSION.i386.rpm
RPM помещает данные в /var/lib/mysql. RPM также создает соответствующие записи в /etc/rc.d, чтобы запустить сервер автоматически при начальной загрузке. Имейте в виду, что старый файл запуска (если таковой был Вами создан) будет затерт.
После установки из файлов RPM mysqld
daemon должен работать,
и Вы должны теперь иметь возможность начать использовать MySQL. Подробности в
разделе "2.4 Послеустановочная
настройка и тестирование".
Если что-то пошло не так, Вы можете найти подробную информацию в разделе "2.7 Установка MySQL из двоичного дистрибутива".
Следующие команды применимы к заранее откомпилированным двоичным дистрибутивам. Если Вы загружаете исходники, Вы будете должны компилировать и устанавливать их лично.
Если Вы не имеете копию дистрибутива MySQL, Вы должны сначала скачать ее с http://www.mysql.com/downloads/mysql-3.23.html.
Если Вы планируете соединяться с MySQL из некоторой другой программы, Вы, вероятно, также будете нуждаться в драйвере MyODBC. Вы можете скачать его с http://www.mysql.com/downloads/api-myodbc.html.
Чтобы устанавливать любой дистрибутив, разожмите его программой unzip в
некотором пустом каталоге и выполните программу Setup.exe
.
По умолчанию MySQL-Windows конфигурирован так, чтобы быть установленным в
C:\mysql. Если Вы хотите устанавливать MySQL в другом месте,
установите его сначала в C:\mysql, а потом переместите установку в
то, где Вы хотите ее видеть. Если Вы перемещаете MySQL, Вы должны указать,
где все размещено, с помощью опции --basedir
при запуске
сервера. Например, если Вы переместили MySQL в D:\programs\mysql,
Вы должны запустить mysqld
так:
C:\> D:\programs\mysql\bin\mysqld --basedir D:\programs\mysql
Использование mysqld --help
отображает все параметры, которые
понимает mysqld
!
Со всеми более новыми MySQL версиями Вы можете также создавать файл C:\my.cnf, который хранит любые заданные по умолчанию параметры для сервера MySQL. Скопируйте файл \mysql\my-xxxxx.cnf в C:\my.cnf и отредактируйте его, чтобы он соответствовал Вашей установке. Обратите внимание, что Вы должны определить все пути с помощью `/' вместо `\'. Если Вы используете `\', Вы должны определить этот символ дважды, так как `\' представляет собой управляющий символ в MySQL.
Начиная с MySQL 3.23.38, Windows-дистрибутив включает файлы для
нормального и для MySQL-Max. Основная польза от
использования нормальной версии mysqld.exe
в том, что она
работает немного быстрее и использует меньшее количество ресурсов.
Имеется список различных серверов MySQL, которые Вы можете использовать:
mysqld | Откомпилирован с полной отладкой и автоматической проверкой распределения памяти, символическими связями, таблицами BDB и InnoDB. |
mysqld-opt | Оптимизирован без поддержки для транзакционных таблиц. |
mysqld-nt | Оптимизирован для NT с поддержкой именованных каналов. Вы можете выполнять эту версию и на Win98, но в этом случае, никакие именованные каналы не будут созданы, и Вы должны иметь установленный TCP/IP. |
mysqld-max | Оптимизирован с поддержкой символических связей, а также таблиц BDB и InnoDB. |
mysqld-max-nt | Подобно mysqld-max ,
но с поддержкой именованных каналов. |
Все приведенные выше бинарные файлы оптимизированы для процессора Pentium Pro, но должны работать на любом процессоре Intel >= i386.
ОБРАТИТЕ ВНИМАНИЕ: Если Вы хотите использовать таблицы InnoDB, имеются некоторые параметры запуска, которые должны быть определены в Вашем файле my.ini! Подробности в разделе " 7.6.2 Опции запуска InnoDB".
Проверьте домашнюю страницу MySQL http://www.mysql.com для поиска информации относительно текущей версии и того, где ее искать.
Наше основное зеркало загрузки размещено на:
http://mirrors.sunsite.dk/mysql
Если Вы заинтересованы в создании своего зеркала MySQL, Вы можете
использовать анонимный rsync: rsync://sunsite.dk/ftp/mirrors/mysql
. Пожалуйста, пошлите e-mail на
webmaster@mysql.com с сообщением о зеркале, которое будет добавлено к
приведенному ниже списку.
Если Вы имеете проблемы при загрузке с нашего основного сайта, попробуйте использовать одно из зеркал, перечисленных в списке ниже.
Пожалуйста, сообщите о плохих или устаревших зеркалах на webmaster@mysql.com.
Европа:
Северная Америка:
Южная Америка:
Азия:
Африка:
Авторы используют GNU Autoconf, так что возможно портирование MySQL на все современные системы с поддержкой потоков Posix и языка C++. C++ нужен только, чтобы откомпилировать код клиента, но не потоков. Все программное обеспечение разрабатывается прежде всего на Sun Solaris (Versions 2.5-2.7) и на SuSE Linux Version 7.x.
Обратите внимание, что для многих операционных систем, местная поддержка потоков работает только в последних версиях. MySQL компилировался успешно на следующих комбинациях пакетов потоков/операционных систем:
glibc
2.0.7+.
Подробности в разделе 2.6.1 Замечания по Linux
(все версии Linux).
Обратите внимание, что не все платформы одинаково хорошо подходят для работы MySQL. Как хорошо некоторая платформа подходит для задания с высокой загрузкой, определена следующими факторами:
Основываясь на вышеупомянутых критериях, можно сказать, что самые лучшие платформы для MySQL на сегодняшний день: на x86 SuSE Linux 7.1, с ядром 2.4 и ReiserFS (или любой подобный дистрибутив Linux), а на Sparc Solaris 2.7 или 2.8. FreeBSD занимает третье место, но в ней идет реконструкция библиотеки потоков, глядишь, и выплывет наверх...
Пожалуйста, обратите внимание, что сравнение выше не говорит, что одни OS вообще лучше или хуже, чем другие. Мы говорим относительно выбора OS для специализированной цели, а именно, для работы с MySQL, и сравниваем платформы только в этом отношении.
Первое решение состоит в том, хотите ли Вы использовать последний выпуск для разработки или последний устойчивый выпуск:
Второе решение состоит в том, хотите ли Вы использовать исходники или двоичный дистрибутив. В большинстве случаев Вы должны использовать двоичный дистрибутив, если таковой существует для Вашей платформы, поскольку это в общем-то будет проще, чем установить все из исходников.
В следующих случаях лучше использовать именно исходники:
MySQL
отмечен суффиксом -max
и сконфигурировано с
теми же самыми параметрами, что и mysqld-max
. Подробности в
разделе "4.7.5 mysqld-max, расширенный сервер
mysqld". Если Вы хотите использовать MySQL-Max
RPM, Вы
должны сначала установить стандартный MySQL
RPM.
mysqld
с некоторыми
дополнительными свойствами, которых нет в стандартных двоичных дистрибутивах.
Имеется список наиболее часто встречающихся дополнительных параметров,
которые Вы можете хотеть использовать:
--with-berkeley-db
--with-innodb
--with-raid
--with-libwrap
--with-named-z-lib (это уже выполнено для некоторых
из двоичных дистрибутивов)
--with-debug[=full]
pgcc
) или
использовать параметры транслятора, которые являются лучше оптимизированными
для Вашего процессора.
MySQL при своем именовании версий использует числа выпуска, которые
состоят из трех чисел и суффикса. Например, имя выпуска, подобное
mysql-3.21.17-beta
, интерпретируется таким образом:
3
) описывает формат файла. Все выпуски
версии 3 имеют тот же самый формат файла.
21
) задает уровень выпуска. Обычно имеется два
выпуска. Один стабильный (сейчас это 23
), второй разрабатываемый
(сейчас 4.0
). Обычно оба устойчивы, но версия для разработки
может иметь причуды, отсутствие документации по новым свойствам или может
не компилироваться на некоторых системах.
17
) представляет собой номер версии внутри
уровня выпуска. Это число будет увеличено для каждого нового дистрибутива.
Обычно Вы должны скачать последнюю версию для того уровня выпуска, который
Вы себе выбрали.
beta
) указывает уровень стабильности выпуска.
Возможны следующие суффиксы:
alpha
указывает, что выпуск содержит некоторый большой
раздел нового кода, который не был оттестирован на 100%. Известные ошибки
(обычно там их нет) должны быть зарегистрированы в разделе News. Имеются
также новые команды и расширения в большинстве alpha-версий. Активная
разработка, которая может включать серьезные изменения кода, может
происходить на alpha-версии, но все будет проверено перед выполнением
выпуска. Не должно быть никаких известных ошибок в любом выпуске MySQL.
beta
означает, что весь новый код был проверен. Никакие
новые свойства, которые могли бы вызывать искажение на старом коде, не были
добавлены. Не должно иметься никаких известных ошибок. Версия изменяется от
alpha к beta когда нет сообщений о фатальных ошибках внутри alpha-версии по
крайней мере за последний месяц, и не планируется добавлять любые свойства,
которые могли бы сделать любую старую команду ненадежной.
gamma
это такая бета-версия, которая была проверена
временем, и, вроде бы, работает прекрасно. Только маленькие изменения могут
быть внесены. Это то, что многие другие компании называют релизом.
Все версии MySQL проходят стандартные и эталонные тесты, чтобы гарантировать, что они относительно безопасны.
Обратите внимание, что все выпуски были проверены по крайней мере с:
crash-me
Этот раздел описывает заданное по умолчанию размещение каталогов, созданных при установке.
Двоичный дистрибутив установлен, распаковываясь в расположение установки, которое Вы выбираете (обычно /usr/local/mysql), и создает следующие каталоги в этом расположении:
Каталог | Содержимое |
bin | Клиентские программы и сервер
mysqld |
data | Файлы протоколов и баз данных |
include | Заголовочные (header) файлы |
lib | Библиотеки |
scripts | mysql_install_db |
share/mysql | Файлы сообщений об ошибках |
sql-bench | Бенчмарки (эталонные тесты) |
Дистрибутив из исходных кодов будет установлен после того, как Вы его сконфигурируете и откомпилируете. По умолчанию, шаг установки копирует файлы в следующие подкаталоги в /usr/local:
Каталог | Содержимое |
bin | Клиентские программы и скрипты |
include/mysql | Заголовочные (header) файлы |
info | Документация в формате Info |
lib/mysql | Библиотеки |
libexec | Сервер mysqld |
share/mysql | Файлы сообщений об ошибках |
sql-bench | Бенчмарки (эталонные тесты)+тест
crash-me |
var | Файлы протоколов и баз данных |
Внутри каталога установок, размещение установки из исходного кода отличается от таковой из двоичного дистрибутива так:
mysqld
установлен в каталог libexec, а
не в каталог bin.
mysql_install_db
установлен в каталог
/usr/local/bin, а не в каталог /usr/local/mysql/scripts.
Вы можете создать Ваш собственный двоичный дистрибутив из откомпилированных исходников (иногда очень полезно!), выполняя скрипт scripts/make_binary_distribution.
MySQL развивается быстро. MySQL AB использует следующую стратегию при модифицировании MySQL:
Текущий устойчивый выпуск: Version 3.23. Авторы пакета уже переместили активную разработку в Version 4.0. Ошибки все еще будут отлавливаться и исправляться в устойчивой версии по мере их обнаружения.
В MySQL AB обеспечивают набор двоичных дистрибутивов, которые компилируются непосредственно авторами пакета, или в местах, где заказчики доброжелательно дали доступ к их машинам.
Эти дистрибутивы сгенерированы scripts/make_binary_distribution
и сконфигурированы со следующими трансляторами и параметрами:
gcc
2.7.2.1
CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors" ./configure
--prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex
--enable-assembler
egcs
1.0.3a или 2.90.27 или gcc
2.95.2 и новее
CC=gcc CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors
-fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql
--with-low-memory --with-extra-charsets=complex --enable-assembler
gcc
2.8.1
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
--with-low-memory --with-extra-charsets=complex
pgcc
2.90.29 (egcs
1.0.3a)
CFLAGS="-O3 -mpentium -mstack-align-double" CXX=gcc CXXFLAGS="-O3
-mpentium -mstack-align-double -felide-constructors -fno-exceptions
-fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler
--with-mysqld-ldflags=-all-static --with-extra-charsets=complex
gcc
2.95.2
CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro
-felide-constructors -fno-exceptions -fno-rtti" ./configure
--prefix=/usr/local/mysql --enable-assembler
--with-mysqld-ldflags=-all-static --disable-shared
--with-extra-charset=complex
gcc
2.7-95q4
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
--with-extra-charsets=complex
gcc
2.7.2.2
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
--with-extra-charsets=complex
gcc
2.8.1
CC=gcc CFLAGS=-O CXX=gcc CXXFLAGS=-O3 ./configure
--prefix=/usr/local/mysql --with-low-memory
--with-extra-charsets=complex
gcc
2.8.0
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
--with-extra-charsets=complex
gcc
2.7.2.1
CC=gcc CXX=gcc CXXFLAGS=-O ./configure --prefix=/usr/local/mysql
--with-extra-charsets=complex
gcc
2.7.2
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
--with-extra-charsets=complex
Любой, кто имеет более оптимальные параметры для любой из конфигураций, перечисленных выше, может всегда отправлять по почте их в лист рассылки разработчиков по адресу internals@lists.mysql.com.
RPM-дистрибутивы до MySQL Version 3.22 создавались пользователями. Начиная с версии Version 3.22, RPM-пакеты генерируются в MySQL AB.
Если Вы хотите компилировать версию для отладки MySQL, Вы должны добавить
--with-debug
или --with-debug=full
к вышеупомянутым
строкам выбора конфигурации и удалить все параметры
-fomit-frame-pointer
.
Как только Вы установили MySQL (неважно, из какого типа дистрибутива) Вы должны инициализировать таблицы предоставления привилегий, запустить сервер и удостовериться, что он работает нормально. Вы можете также принять меры, чтобы сервер был запущен и остановлен автоматически при запуске или парковке ОС Вашего компьютера.
Обычно Вы устанавливаете таблицы предоставления привилегий и запускаете сервер для установки из исходников примерно так:
shell> ./scripts/mysql_install_db shell> cd mysql_installation_directory shell> ./bin/safe_mysqld --user=mysql &
Для двоичного дистрибутива (не RPM или pkg-пакетов!), скомандуйте:
shell> cd mysql_installation_directory shell> ./bin/mysql_install_db shell> ./bin/safe_mysqld --user=mysql &
Это создает базу данных mysql
, которая хранит все привилегии,
базу данных test
, которую Вы можете использовать, чтобы
проверить MySQL, а также записи для пользователя, который выполняет
mysql_install_db
и для администратора root
(без
любых паролей). Это также запускает сервер mysqld
.
Скрипт mysql_install_db
не будет перезаписывать старые
таблицы привилегии, так что должен безопасно выполняться в любых
обстоятельствах. Если Вы не хотите иметь базу данных test
, Вы
можете удалить ее командой mysqladmin -u root drop test
.
Тестирование наиболее легко выполняется из верхнего каталога дистрибутива MySQL. Для двоичного дистрибутива это Ваш каталог установки (обычно что-то вроде /usr/local/mysql). Для исходников это основной каталог Вашего дерева исходного кода MySQL.
В командах, показанных ниже в этом разделе и в следующих подразделах,
BINDIR
означает путь к месту, в которое установлены программы,
подобные mysqladmin
и safe_mysqld
. Для двоичного
дистрибутива это каталог bin внутри дистрибутива. Для исходников
BINDIR
, вероятно, /usr/local/bin, если Вы не определили
другой каталог установок вместо /usr/local, когда Вы выполнили
configure
. EXECDIR
задает расположение, в которое
установлен сервер mysqld
. Для двоичного дистрибутива это
BINDIR
. Для исходников EXECDIR
, вероятно, будет
/usr/local/libexec.
Тестирование подробно описано ниже:
mysqld
и
установите начальные таблицы предоставления привилегий MySQL, содержащие
привилегии, которые определяют, как пользователям позволяется соединяться с
сервером. Это обычно сделается скриптом mysql_install_db
:
shell> scripts/mysql_install_db
Обычно mysql_install_db
должен быть выполнен только в первый
раз, когда Вы устанавливаете MySQL. Следовательно, если Вы проводите апгрейд
существующей установки, Вы можете пропустить этот шаг. (Однако,
mysql_install_db
совершенно безопасен и не будет модифицировать
никакие таблицы, которые уже существуют, так что если Вы не уверены в том,
что и зачем делаете, Вы можете всегда выполнять
mysql_install_db
.)
Скрипт mysql_install_db
создает шесть таблиц
(user
, db
, host
,
tables_priv
, columns_priv
и func
) в
базе данных mysql
. Описание начальных привилегий дано в разделе
"4.3.4 Установка начальных
привилегий MySQL". Кратко, эти привилегии позволяют MySQL-пользователю
root
делать что угодно, а любому другому пользователю только
создавать или использовать базы данных с именем 'test'
или
начинающемся на test_
.
Если Вы не устанавливаете таблицы предоставления привилегий, следующая ошибка появится в журнале, когда Вы запускаете сервер:
mysqld: Can't find file: 'host.frm'Вышеупомянутое может также случаться с двоичным дистрибутивом MySQL, если Вы не запускаете MySQL, выполняя именно
./bin/safe_mysqld
!
Подробности в разделе "4.7.2 safe_mysqld,
обертка вокруг mysqld".
Вы должны выполнить mysql_install_db
как root
.
Однако, если Вы считаете это невозможным, можете выполнять сервер MySQL как
непривилегированный пользователь (не-root
), при условии, что
этот пользователь может читать и писать файлы в каталоге баз данных. Команды
для управления MySQL от имени непривилегированного пользователя есть в
разделе "8.3.2 Как запустить MySQL
от имени нормального пользователя".
Если Вы имеете проблемы с mysql_install_db
, изучите раздел
"2.4.1 Проблемы с запуском
mysql_install_db
".
Имеются некоторые варианты запуска mysql_install_db
, поскольку
это обеспечивается в дистрибутиве MySQL:
mysql_install_db
перед его
запуском, изменять начальные привилегии, которые будут установлены в таблицы
предоставления привилегий. Это полезно, если Вы хотите устанавливать MySQL на
большом количестве машин с теми же самыми привилегиями. В этом случае Вы,
вероятно, должны будете только добавить несколько дополнительных инструкций
INSERT
к таблицам mysql.user
и
mysql.db
!
mysql_install_db
, а затем
использовать mysql -u root mysql
, чтобы соединиться с таблицами
предоставления привилегий как MySQL-пользователь root
и выдавать
инструкции SQL, чтобы непосредственно изменить таблицы предоставления.
mysql_install_db
.shell> cd mysql_installation_directory shell> bin/safe_mysqld &Если Вы имеете проблемы при запуске сервера, обратитесь за дополнительной информацией к разделу "2.4.2 Проблемы при запуске сервера MySQL".
mysqladmin
, чтобы проверить, что сервер
запустился. Следующие команды обеспечивают простой тест, чтобы проверить, что
сервер работает и отвечает на подключения:
shell> BINDIR/mysqladmin version shell> BINDIR/mysqladmin variablesВывод
mysqladmin version
немного изменяется в зависимости от
Вашей платформы и версии MySQL, но должен быть подобен показанному ниже:
shell> BINDIR/mysqladmin version mysqladmin Ver 8.14 Distrib 3.23.32, for linux on i586 Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB This software comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to modify and redistribute it under the GPL license Server version 3.23.32-debug Protocol version 10 Connection Localhost via Unix socket TCP port 3306 UNIX socket /tmp/mysql.sock Uptime: 16 sec Threads: 1 Questions: 9 Slow queries: 0 Opens: 7 Flush tables: 2 Open tables: 0 Queries per second avg: 0.000 Memory in use: 132K Max memory used: 16773KЧтобы узнать подробно о том, что еще Вы можете делать с
BINDIR/mysqladmin
, вызовите программу с опцией
--help
.
shell> BINDIR/mysqladmin -u root shutdown
safe_mysqld
или непосредственно mysqld
. Например:
shell> BINDIR/safe_mysqld --log &Если
safe_mysqld
сбоит, попробуйте запустить его из каталога
установки MySQL, если Вы еще не там. Если это не работает, обратитесь за
подробностями к разделу "2.4.2 Проблемы
при запуске сервера MySQL".
shell> BINDIR/mysqlshow +-----------+ | Databases | +-----------+ | mysql | +-----------+ shell> BINDIR/mysqlshow mysql Database: mysql +--------------+ | Tables | +--------------+ | columns_priv | | db | | func | | host | | tables_priv | | user | +--------------+ shell> BINDIR/mysql -e "select host,db,user from db" mysql +------+--------+------+ | host | db | user | +------+--------+------+ | % | test | | | % | test_% | | +------+--------+------+Имеется также эталонный набор тестов в каталоге sql-bench (в каталоге установки MySQL), который Вы можете использовать, чтобы сравнить, как MySQL выполняется на различных платформах. Каталог sql-bench/Results хранит результаты выполнения на разных системах. Чтобы выполнять все тесты, введите эти команды:
shell> cd sql-bench shell> run-all-testsЕсли Вы не имеете каталога sql-bench, Вы, вероятно, используете пакет RPM для двоичного дистрибутива. Дистрибутивные пакеты RPM с исходниками включают эталонный каталог. В этом случае, Вы должны сначала установить эталонный набор. Начмная с MySQL Version 3.22, имеются эталонные файлы RPM, названные mysql-bench-VERSION-i386.rpm, которые содержат эталонный код и данные. Если Вы имеете дистрибутив с исходниками, Вы можете также выполнять тесты в подкаталоге tests. Например, чтобы выполнить тест auto_increment.tst, скомандуйте:
shell> BINDIR/mysql -vvf test < ./tests/auto_increment.tstОжидаемые результаты показываются в файле ./tests/auto_increment.res.
mysql_install_db
Цель скрипта mysql_install_db
состоит в том, чтобы
сгенерировать новые таблицы предоставления привилегий MySQL. Это не будет
воздействовать на любые другие данные! Скрипт также не будет делать что-либо,
если Вы уже имеете установленные таблицы предоставления привилегий MySQL!
Если Вы хотите пересоздать Ваши таблицы привилегий, Вы должны сначала
завершить сервер mysqld
, если он работает, а затем выполнить:
mv mysql-data-directory/mysql mysql-data-directory/mysql-old mysql_install_db
Этот раздел перечисляет проблемы, с которыми Вы можете столкнуться, когда
выполняете mysql_install_db
:
mysql_install_db
не устанавливает таблицы
предоставления привилегий.
mysql_install_db
валится после
вывода следующих сообщений:
starting mysqld daemon with databases from XXXXXX mysql daemon endedВ этом случае, Вы должны исследовать журнал очень тщательно! Файл регистрации должен быть размещен в каталоге XXXXXX, указанном в сообщении об ошибке, и он должен указать, почему
mysqld
не запустился.
mysqld
.
mysql_install_db
. Скурипт mysql_install_db
следует
выполнять только однажды, когда Вы устанавливаете MySQL в первый раз.
mysqld
не работает, когда первый
сервер уже запущен.
Can't start server: Bind on TCP/IP port: Address already in use
или Can't start server : Bind on unix socket...
. Подробности в
разделе "4.1.3 Установка
нескольких серверов на одной и той же машине".
mysql_install_db
или mysqld
.
Вы можете определять иной сокет и временный каталог следующим образом:
shell> TMPDIR=/some_tmp_dir shell> MYSQL_UNIX_PORT=/some_tmp_dir/mysqld.sock shell> export TMPDIR MYSQL_UNIX_PORTПодробности есть в разделе " 8.4.5 Как защитить или менять файл сокета MySQL /tmp/mysql.sock". some_tmp_dir должен быть путем к некоторому каталогу, для которого Вы имеете разрешение на запись. Подробности в разделе "Приложение 2. Переменные окружения ". После этого Вы должны выполнить
mysql_install_db
и запустить
сервер с помощью этих команд:
shell> scripts/mysql_install_db shell> BINDIR/safe_mysqld &
mysqld
немедленно рушится.
glibc
старше,
чем 2.0.7-5, Вы должны удостовериться, что установили все заплаты для
glibc
! Имеется много информации относительно этого в архиве
почты MySQL. Связь с архивом почты доступна интерактивно на
http://www.mysql.com/documentation. Также следует ознакомиться с разделом
"2.6.1 Замечания по Linux (все версии Linux)".
Вы можете также запустить mysqld
вручную, используя опции
--skip-grant-tables
и добавлять информацию о привилегиях
самостоятельно, используя mysql
:
shell> BINDIR/safe_mysqld --skip-grant-tables & shell> BINDIR/mysql -u root mysqlИз
mysql
вручную выполните команды из
mysql_install_db
. Удостоверьтесь, что позже Вы выполняете
mysqladmin flush-privileges
или mysqladmin reload
,
чтобы сервер перезагрузил таблицы предоставления.Если Вы собираетесь использовать таблицы, которые поддерживают транзакции (BDB, InnoDB), Вы должны сначала создать файл my.cnf и установить параметры запуска для тех типов таблиц, которые Вы планируете использовать. Подробности в разделе "7 Типы таблиц MySQL".
Вообще, Вы запускаете сервер mysqld
одним из трех путей:
mysql.server
. Этот скрипт используется прежде
всего при запуске системы, и описан более подробно в разделе
"2.4.3
Автоматический запуск и останов MySQL".
safe_mysqld
, который пробует определить
соответствующие параметры для mysqld
и затем выполняет его с
этими параметрами.. Подробности в разделе "
4.7.2 safe_mysqld, обертка вокруг mysqld".
mysqld
как сервис:
bin\mysqld-nt --install # Install MySQL as a serviceВы можете запускать и выключать сервер
mysqld
так:
NET START mysql NET STOP mysqlЗаметьте, что в этом случае, Вы не можете использовать каких-либо опций для
mysqld
! Можно удалить сервис:
bin\mysqld-nt --remove # remove MySQL as a service
mysqld
непосредственно.Когда mysqld
запускается, он переходит в каталог данных, где
ожидает найти базы данных. Именно там будут записываться файлы протокола и
pid (process ID).
Расположение каталога данных зависит от настроек при построении пакета.
Однако, если mysqld
ожидает найти каталог данных в одном месте,
а он реально расположился где-нибудь в другом, сервер не будет работать
правильно. Если Вы имеете проблемы с неправильными путями, Вы можете выяснить
то, какие параметры понимает mysqld
и заданные по умолчанию
параметры настройки вызовом mysqld
с опцией --help
.
Вы можете отменять значения по умолчанию, определяя правильные имена
каталогов как параметры командной строки mysqld
. Эти параметры
также могут использоваться и с safe_mysqld
.
Обычно Вы должны сообщить mysqld
только основной каталог, в
который MySQL установлен. Вы можете сделать это с помощью опции
--basedir
. Вы можете также использовать --help
,
чтобы проверить эффект изменения параметров (обратите внимание, что
--help
ДОЛЖНА быть последней опцией в вызове
mysqld
). Конкретный пример:
shell> EXECDIR/mysqld --basedir=/usr/local --help
Как только Вы определите параметры настройки путей к каталогам, запустите
сервер без опции --help
.
Любой метод, который Вы используете, чтобы запустить сервер, в случае
провала отмечает ситуацию в журнале ошибок. Журналы размещены в каталоге
данных (обычно /usr/local/mysql/data для двоичного дистрибутива, в
/usr/local/var для исходников или в \mysql\data\mysql.err
для Windows). Просмотрите каталог данных для поиска файлов с именами формы
host_name.err и host_name.log, где host_name
имя Вашего компьютера сервера. Затем проверьте последние строки файлов:
shell> tail host_name.err shell> tail host_name.log
Если в файле протокола будет найдено нечто вроде:
000729 14:50:10 bdb: Recovery function for LSN 1 27595 failed 000729 14:50:10 bdb: warning: ./test/t1.db: No such file or directory 000729 14:50:10 Can't init databases
Это означает, что Вы не запускали mysqld
с
--bdb-no-recover
, и драйвер Berkeley DB выявил, что что-то пошло
неправильно с журналами, когда пробовал восстанавливать Ваши базы данных.
Чтобы продолжить работу, Вы должны переместить старый журнал Berkeley DB из
каталога баз данных куда-то в другое место, где Вы можете позже исследовать
его. Журналы именованы как log.0000000001, где число увеличивается
через какое-то время.
Если Вы управляете mysqld
с поддержкой таблиц BDB, и
mysqld
падает в дамп ядра при запуске, это может быть из-за
некоторых проблем с файлом регистрации BDB. В этом случае Вы можете
попробовать запускать mysqld
с опцией
--bdb-no-recover
. Если это помогает, то удалите все файлы
log.* из каталога данных и попробуйте снова запустить
mysqld
.
Если Вы получаете следующую ошибку, это означает, что некоторая другая
программа (или другой сервер mysqld
) уже использует TCP/IP порт
или сокет, который пробует использовать mysqld
:
Can't start server: Bind on TCP/IP port: Address already in use или Can't start server : Bind on unix socket...
Используйте ps
, чтобы удостовериться, что Вы не имеете
другого сервера mysqld
. Если Вы не можете его найти, Вы можете
попробовать выполнить команду telnet your-host-name tcp-ip-port-number
и нажать RETURN
несколько раз. Если Вы не получаете
сообщений об ошибках подобно telnet: Unable to connect to remote host:
Connection refused
, стало быть что-то использует TCP/IP порт, который
пробует занять mysqld
. Подробности в разделах
"2.4.1 Проблемы с запуском
mysql_install_db
" и в
"4.1.4 Выполнение нескольких серверов
на одной и той же машине".
Если mysqld
в настоящее время работает, Вы можете выяснить,
какие параметры настройки он использует, выполняя эту команду:
shell> mysqladmin variables
или
shell> mysqladmin -h 'your-host-name' variables
Если safe_mysqld
сервер запускает, но Вы не можете
соединиться с ним, Вы должны удостовериться, что имеете запись в файле
/etc/hosts, которая выглядит следующим образом:
127.0.0.1 localhost
Эта проблема происходит только на системах, которые не имеют рабочую библиотеку потоков, и для которых MySQL должен быть сконфигурирован так, чтобы использовать MIT-pthreads.
Если Вы не можете запустить mysqld
, Вы можете попробовать
сделать файл трассировки, чтобы найти проблему. Подробности в разделе
"6.1.2 Создание файлов трассировки
".
Если Вы используете InnoDB-таблицы, обратитесь к специфическим параметрам запуска. Подробности в разделе "7.6.2 Параметры запуска InnoDB".
Если Вы используете таблицы BDB (Berkeley DB), Вы должны ознакомиться с различными специфическими параметрами запуска BDB. Подробности в разделе "7.5.3 Параметры запуска BDB".
Скрипты mysql.server
и safe_mysqld
могут
использоваться, чтобы запустить сервер автоматически при запуске системы.
Скрипт mysql.server
может также использоваться для того, чтобы
остановить сервер при парковке системы.
Скрипт mysql.server
может использоваться, чтобы запустить или
остановить сервер, вызывая его с параметрами start
или
stop
:
shell> mysql.server start shell> mysql.server stop
mysql.server
может быть найден в каталоге
share/mysql установочного каталога MySQL или в каталоге
support-files дерева исходников MySQL.
Прежде, чем mysql.server
запустит сервер, он сменит текущий
каталог на каталог установки MySQL, а затем вызовет safe_mysqld
.
Вы должны подредактировать mysql.server
, если Вы имеете двоичный
дистрибутив, который Вы установили в ненормативное расположение. Измените
параметр в вызове cd
на соответствующий каталог перед вызовом
safe_mysqld
. Если Вы хотите, чтобы сервер работал от имени
определенного пользователя, добавьте соответствующую строку user
к файлу /etc/my.cnf, как показано ниже в этом разделе.
mysql.server stop
завершает сервер, посылая ему сигнал. Вы
можете достичь того же эффекта вручную, выполнив команду
mysqladmin shutdown
.
Вы можете добавить команды запуска и завершения к соответствующим местам в
файлах /etc/rc*, когда Вы начинаете использовать MySQL для
промышленных прикладных программ. Обратите внимание, что, если Вы изменяете
mysql.server
, а потом проапгрейдите MySQL, измененная версия
будет перезаписана, так что Вы должны сделать копию Вашей версии.
Если Ваша система использует /etc/rc.local, чтобы запустить внешние скрипты, Вы должны дописать к нему следующее:
/bin/sh -c 'cd /usr/local/mysql ; ./bin/safe_mysqld --user=mysql &'
Вы можете также добавлять параметры для mysql.server
в
глобальный файл /etc/my.cnf. Типичный файл /etc/my.cnf
может выглядеть следующим образом:
[mysqld] datadir=/usr/local/mysql/var socket=/var/tmp/mysql.sock port=3306 user=mysql [mysql.server] basedir=/usr/local/mysql
Скрипт mysql.server
понимает следующие параметры:
datadir
, basedir
и pid-file
.
Следующая таблица показывает, какие группы опций читает из файлов настройки конкретный скрипт:
Скрипт | Группы опций |
mysqld | mysqld и
server |
mysql.server | mysql.server ,
mysqld и server |
safe_mysqld | mysql.server ,
mysqld и server |
Вы можете всегда перемещать форму MySQL и файлы данных между различными
версиями на той же самой архитектуре, пока Вы имеете ту же самую основную
версию MySQL. Текущая основная версия 3. Если Вы изменяете набор символов при
управлении MySQL (который может также изменять порядок сортировки), Вы должны
выполнить myisamchk -r -q
на всех таблицах. Иначе Ваши индексы
нельзя будет упорядочивать правильно.
Если Вы боитесь новых версий, Вы можете всегда переименовать Ваш старый
mysqld
на что-то вроде mysqld
-'old-version-number'.
Если Ваш новый mysqld
сделает что-то непредвиденное, Вы можете
просто закрыть его и перезапустить старую версию mysqld
!
Когда Вы делаете обновление, Вы, конечно, должны также зарезервировать Ваши старые базы данных.
Если после обновления Вы испытываете проблемы с перекомпиляцией программ
пользователя, подобно Commands out of sync
, или получаете
неожиданные дампы ядра, Вы, вероятно, использовали старые заголовки или
не тот библиотечный файл при компиляции Ваших программ. В этом случае Вы
должны проверить дату для Вашего файла mysql.h и библиотеки
libmysqlclient.a, чтобы проверить, что они из нового дистрибутива
MySQL. Если это не так, перекомпилируйте Ваши программы!
Если Вы получаете некоторые проблемы, например, новый сервер
mysqld
не хочет запускаться, или Вы не можете соединиться без
пароля, проверьте, что Вы не имеете старый файл my.cnf из Вашей
старой установки! Вы можете проверить это командой program-name
--print-defaults
. Если это выводит что-нибудь другое, чем имя
программы, Вы имеете активный файл my.cnf
, который будет
воздействовать на все вокруг!
Неплохо бы повторно установить дистрибутив Msql-Mysql-modules
всякий раз, когда Вы устанавливаете новый выпуск MySQL, особенно, если Вы
обращаете внимание на нехорошие признаки, типа Ваших скриптов
DBI
, сбрасывающих дамп ядра после апгрейда MySQL.
Вы можете использовать Ваши старые файлы данных без модификаций с Version
4.0. Если Вы хотите перемещать Ваши данные с сервера MySQL 4.0 на старый
сервер, Вы должны использовать mysqldump
.
Старые клиенты могут работать с новым сервером версии 4.0 без проблем.
Следующий список сообщает, что Вы должны не упустить при обновлении до Version 4.0;
mysql_drop_db
,
mysql_create_db
и mysql_connect
теперь не
поддерживаются. Для совместимости можно компилировать MySQL с опцией
USE_OLD_FUNCTIONS
.
TRUNCATE TABLE
, когда Вы хотите
удалить все строки из таблицы. (Потому, что TRUNCATE TABLE
работает быстрее, чем DELETE FROM table_name
).
LOCK TABLES
или
транзакцию при попытке выполнить TRUNCATE TABLE
или
DROP DATABASE
.MySQL Version 3.23 поддерживает таблицы нового типа MyISAM
и
старого типа ISAM
. Вы не должны преобразовывать Ваши старые
таблицы, чтобы использовать их с Version 3.23. По умолчанию, все новые
таблицы будут созданы с типом MyISAM
(если Вы не запускаете
mysqld
с опцией --default-table-type=isam
). Вы
можете изменять таблицы ISAM
на таблицы MyISAM
командой ALTER TABLE table_name TYPE=MyISAM
или Perl-скриптом
mysql_convert_table_format
.
Клиенты версий 3.22 и 3.21 могут работать с новым сервером версии 3.23 без каких-либо проблем.
Следующий список сообщает, что Вы должны не упустить при обновлении до Version 3.23:
tis620
,
должны быть подправлены с помощью myisamchk -r
или REPAIR
TABLE
.
DROP DATABASE
на символически связанной базе
данных, связь и первоначальная база данных будут удалены. Этого не случалось
в версии 3.22 потому, что выбор конфигурации не обнаруживал системный вызов
readlink
).
OPTIMIZE TABLE
теперь работает только для таблиц
MyISAM. Для других типов Вы можете использовать
ALTER TABLE
, чтобы оптимизировать таблицу. В течение работы
OPTIMIZE TABLE
обрабатываемая таблица теперь блокирована.
mysql
теперь по умолчанию запускается с опцией
--no-named-commands (-g)
. Эта опция может быть заблокирована с
помощью --enable-named-commands (-G)
. Это может вызывать
проблемы несовместимости в некоторых случаях, например, в скриптах SQL,
которые используют именованные команды без точки с запятой! Длинный формат
команд все еще работает из первой строки.
german
) символьный порядок
сортировки, Вы должны обработать все Ваши таблицы с isamchk -r
,
поскольку авторы пакета сделали некоторые изменения в порядке сортировки!
IF
теперь будет зависеть
от обоих параметров, а не только от первого параметра.
AUTO_INCREMENT
не будет работать с отрицательными числами.
Причина этого в том, что отрицательные числа вызывали проблемы при переходе
от -1 к 0. AUTO_INCREMENT
теперь для таблиц MyISAM работает
намного быстрее, чем прежде. Для таблиц MyISAM старые числа больше
многократно не используются, даже если Вы удаляете строки из таблицы.
CASE
, DELAYED
, ELSE
,
END
, FULLTEXT
, INNER
,
RIGHT
, THEN
и WHEN
теперь представляют
собой зарезервированные слова.
FLOAT(X)
теперь истинный тип с плавающей запятой, а не
значение с фиксированном числом десятичных чисел.
DECIMAL(length,dec)
параметр длины больше не
включает место для знака или десятичной отметки.
TIME
теперь должна иметь один из следующих форматов:
[[[DAYS] [H]H:]MM:]SS[.fraction]
или
[[[[[H]H]H]H]MM]SS[.fraction]
LIKE
теперь сравнивает строки, использующие те же самые
символьные правила сравнения, что и =
. Если Вы требуете
старого поведения, Вы можете откомпилировать MySQL с параметром
CXXFLAGS=-DLIKE_CMP_TOUPPER
.
REGEXP
теперь нечувствителен к регистру для нормальных (не
двоичных) строк.
CHECK TABLE
или myisamchk
для таблиц
MyISAM
(.MYI
) и isamchk
для
ISAM-таблиц (.ISM
).
mysqldump
были совместимыми
между MySQL Version 3.22 и Version 3.23, Вы не должны использовать опции
--opt
или --full
в вызове mysqldump
.
DATE_FORMAT()
чтобы
удостовериться, что имеется символ `%' перед каждым символом
управления форматом данных.
mysql_fetch_fields_direct
теперь функция (раньше это было
макрокомандой) и возвращает указатель на MYSQL_FIELD
вместо
MYSQL_FIELD
.
mysql_num_fields()
больше не может использоваться на объекте
MYSQL*
: это теперь функция, которая берет как параметр
MYSQL_RES*
. Вы должны теперь использовать вместо этого
mysql_field_count()
.
SELECT DISTINCT ...
почти всегда
сортировался. В Version 3.23 Вы должны использовать GROUP BY
или
ORDER BY
, чтобы получить сортируемый вывод.
SUM()
теперь возвращает NULL
вместо 0, если не
имеется никаких строк соответствий. Это согласно ANSI SQL.
AND
или OR
со значениями NULL
теперь возвратит NULL
вместо 0. Это обычно воздействует на
запросы, которые используют NOT
на выражениях с
AND/OR
как NOT NULL
=NULL
.
LPAD()
и RPAD()
сократит строку результата, если
она более длинная, чем заданный параметр длины.Ничего такого, что воздействует на совместимость, не изменилось между
Version 3.21 и 3.22. Единственная ловушка в том, что новые таблицы, которые
созданы со столбцами типа DATE
, используют новый способ хранить
дату. Вы не можете обращаться к этим новым полям из старой версии
mysqld
.
После установки MySQL Version 3.22 Вы должны запустить новый сервер, а
затем выполнить скрипт mysql_fix_privilege_tables
. Это добавит
новые привилегии для команды GRANT
. Если Вы забудете сделать
это, получите ошибку Access denied
, когда попробуете
использовать ALTER TABLE
, CREATE INDEX
или
DROP INDEX
. Если Ваш MySQL-пользователь root требует пароль, Вы
должны задать его как параметр mysql_fix_privilege_tables
.
интерфейс C API для mysql_real_connect()
изменился. Если Вы
имеете старую программу-клиента, которая вызывает эту функцию, Вы должны
поместить 0
в новый параметр db
(или переписать
клиента, чтобы послать элемент db
, чтобы делать более быстрые
подключения). Вы должны также вызвать mysql_init()
перед вызовом
mysql_real_connect()
! Это изменение было выполнено, чтобы
позволить новой функции mysql_options()
сохранять параметры в
структуре драйвера MYSQL
.
Переменная mysqld
key_buffer
переименована в
key_buffer_size
, но Вы все еще можете использовать старое имя в
Ваших файлах запуска.
Если Вы управляете версией старше, чем Version 3.20.28, и хотите перейти на Version 3.21, Вы должны сделать следующее:
Вы можете запустить сервер mysqld
Version 3.21 вызовом
safe_mysqld --old-protocol
, чтобы использовать с клиентами из
дистрибутива Version 3.20. В этом случае новая клиентская функция
mysql_errno()
не будет возвращать серверных ошибок, только
CR_UNKNOWN_ERROR
(но это работает для ошибок клиента), а сервер
использует старый способ проверки пароля функцией password()
.
Если Вы НЕ используете опцию --old-protocol
с mysqld
, Вы должны сделать следующие изменения:
scripts/add_long_password
должен быть выполнен, чтобы
преобразовать поле Password
в таблице mysql.user
к типу CHAR(16)
.
mysql.user
(чтобы стать 62-разрядными).
MySQL Version 3.20.28 и выше может обрабатывать новый формат таблицы
user
без того, чтобы воздействовать на клиентуру. Если Вы имеете
MySQL версии ниже, чем Version 3.20.28, пароли больше не будут работать с
ним, если Вы преобразуете таблицу user
.
Новый код клиентов работает с сервером mysqld
3.20.x, так
что, если Вы испытываете проблемы с 3.21.x, Вы можете использовать старый
сервер 3.20.x без того, чтобы перекомпилировать клиентуру еще раз.
Если Вы не используете опцию --old-protocol
с
mysqld
, старая клиентура выдаст сообщение об ошибке:
ERROR: Protocol mismatch. Server Version = 10 Client Version = 9
Новый интерфейс Perl DBI
/DBD
также поддерживает
старый интерфейс mysqlperl
. Единственное изменение, которое Вы
должны сделать, если Вы используете интерфейс mysqlperl
: нужно
заменить параметры в функции connect()
. Новые аргументы:
host
, database
, user
и
password
(параметры user
и password
теперь поменялись местами).
Следующие изменения могут воздействовать на запросы в старых программах:
HAVING
теперь должно быть определено перед любым
предложением ORDER BY
.
LOCATE()
переставлены местами.
DATE
, TIME
и TIMESTAMP
.Если Вы используете MySQL Version 3.23, Вы можете копировать файлы
.frm
, .MYI
и .MYD
между различным
архитектурами, которые поддерживают тот же самый формат с плавающей запятой.
MySQL ISAM
-файлы данных и индекса (.ISD и
*.ISM, соответственно) зависимы от архитектуры. Если Вы хотите
переместить Ваши прикладные программы на другую машину, которая имеет иную
архитектуру или ОС, Вы не должны пробовать перемещать базу данных, просто
копируя файлы на другую машину. Вместо этого используйте
mysqldump
.
По умолчанию mysqldump
создаст файл с инструкциями SQL. Вы
можете затем передать файл на другую машину и подать его на ввод клиента
mysql
.
Вызов mysqldump --help
покажет то, какие параметры являются
доступными. Если Вы перемещаете данные к более новой версии MySQL, Вы должны
использовать mysqldump --opt
с более новой версией, чтобы
получить быстрый, компактный дамп.
Самый простой (хотя не самый быстрый) способ перемещать базу данных между двумя машинами состоит в том, чтобы выполнить следующие команды на машине, на которой база данных размещена сейчас:
shell> mysqladmin -h 'other hostname' create db_name shell> mysqldump --opt db_name | \ mysql -h 'other hostname' db_name
Если Вы хотите копировать базу данных с удаленной машины через медленную сеть, Вы можете использовать:
shell> mysqladmin create db_name shell> mysqldump -h 'other hostname' --opt --compress db_name \ | mysql db_name
Вы можете также сохранять результат в файле, затем передавать файл целевой машине и загружать файл в базу данных там. Например, Вы можете сбросить в дамп базу данных на исходной машине подобно этому:
shell> mysqldump --quick db_name | gzip > db_name.contents.gz
Файл, созданный в этом примере сжат. Затем передайте это файл целевой машине и выполните эти команды там:
shell> mysqladmin create db_name shell> gunzip < db_name.contents.gz | mysql db_name
Вы можете также использовать mysqldump
и
mysqlimport
, чтобы выполнить передачу базы данных. Для больших
таблиц это намного быстрее, чем простое использование mysqldump
.
В командах, показанных ниже, DUMPDIR
представляет полное имя
каталога, который Вы используете, чтобы сохранить
вывод из mysqldump
.
Сначала создайте каталог для выходных файлов и дампа база данных:
shell> mkdir DUMPDIR shell> mysqldump --tab=DUMPDIR db_name
Затем передайте файлы в каталоге DUMPDIR
соответствующему
каталогу на целевой машине и загрузите файлы в MySQL там:
shell> mysqladmin create db_name # Создать базу данных shell> cat DUMPDIR/*.sql | mysql db_name # Создать таблицы в базе данных shell> mysqlimport db_name DUMPDIR/*.txt # Загрузить данные в таблицы
Также не забудьте скопировать базу данных mysql
потому, что
именно там хранятся таблицы предоставления привилегий (user
,
db
, host
). Вам, вероятно, придется выполнять
команды как MySQL-пользователь root
на новой машине, пока Вы не
имеете на ней базу данных mysql
со старой.
После того, как Вы импортируете базу данных mysql
на новую
машине, выполните mysqladmin flush-privileges
, чтобы сервер
перезагрузил информацию таблицы предоставления привилегий.
Вы можете использовать старый тип таблиц ISAM. Он исчезнет довольно скоро
потому, что MyISAM
лучшая реализация той же самой вещи. ISAM
использует индексB-tree
. Индекс сохранен в файле с расширением
.ISM
, а данные сохранены в файле с расширением
.ISD
. Вы можете проверять/ремонтировать ISAM-таблицы с помощью
команды isamchk
. Подробности в разделе
4.4.6.7 Использование
myisamchk
для ремонта.
ISAM
имеет следующие особенности и свойства:
Большинство из того, что сказано про таблицы MyISAM
, верно и
для таблиц ISAM
. Подробности в разделе
"7.1 Таблицы MyISAM". Главные отличия от
таблиц типа MyISAM
:
pack_isam
вместо myisampack
.
Если Вы хотите преобразовывать ISAM
-таблицу в
MyISAM
-таблицу так, чтобы Вы могли использовать утилиты, типа
mysqlcheck
, используйте команду ALTER TABLE
:
mysql> ALTER TABLE tbl_name TYPE = MYISAM;
Таблицы HEAP
используют хэшированный индекс и хранятся в
памяти. Это делает их очень быстрыми, но если MySQL рухнет, Вы потеряете все
данные, сохраненные в них. HEAP
очень полезны для создания
временных таблиц в памяти!
Внутренние таблицы MySQL HEAP используют 100% динамическое хеширование без
областей переполнения. Не требуется никакого дополнительного пространства,
необходимого для свободных списков. Таблицы HEAP
также не имеют
проблем с удалением+вставкой:
mysql> CREATE TABLE test TYPE=HEAP SELECT ip,SUM(downloads) as down FROM log_table GROUP BY ip; mysql> SELECT COUNT(ip),AVG(down) FROM test; mysql> DROP TABLE test;
Имеются некоторые вещи, которые надлежит учитывать, когда Вы используете
таблицы HEAP
:
MAX_ROWS
в
инструкции CREATE
, чтобы гарантировать, что Вы случайно не
используете всю память.
=
и
<=>
(но зато ОЧЕНЬ быстро!).
HEAP
могут использовать только целые ключи, чтобы
искать строку. Сравните это с таблицами MyISAM
, где любой
префикс ключа может использоваться, чтобы найти строки.
HEAP
используют фиксированный формат длины записи.
HEAP
не поддерживают столбцы BLOB
и
TEXT
.
HEAP
не поддерживают AUTO_INCREMENT
.
HEAP
не поддерживают индекс на столбце
NULL
.
HEAP
.
HEAP
разделены между всей клиентурой (точно так же,
как и любая другая таблица).
ORDER BY
).
HEAP
распределены в маленьких блоках.
Таблицы на 100% динамические (при вставке). Никаких областей переполнения и
никакого дополнительного места ключа не надо. Удаленные строки помещаются в
связанный список и используются, когда Вы вставляете новые данные в таблицу.
HEAP
,
которые Вы хотите использовать в то же самое время.
DELETE FROM
heap_table
, TRUNCATE heap_table
или
DROP TABLE heap_table
.
MyISAM
на таблицу HEAP
.
HEAP
больше, чем
max_heap_table_size
.Память, необходимая для одной строки в таблице HEAP
:
SUM_OVER_ALL_KEYS(max_length_of_key + sizeof(char*) * 2) + ALIGN(length_of_row+1, sizeof(char*))
sizeof(char*)
является 4 на 32-разрядных машинах и 8
на 64-разрядных системах.
По умолчанию MySQL использует набор символов ISO-8859-1 (Latin1) с сортировкой согласно шведскому и финскому языкам. Это набор символов, подходящий в США и Западной Европе.
Все стандартные программы MySQL компилируются с поддержкой
--with-extra-charsets=complex
. Это добавляет код ко всем
стандартным программам, чтобы они были способны обработать
latin1
и все многобайтные наборы символов. Другие наборы
символов будут загружены из файла определения набора символов тогда, когда
это будет необходимо.
Набор символов определяет то, какие символы позволяются в именах, и в
каком порядке сортируются инструкции ORDER BY
и
GROUP BY
в операторе выполнения запроса SELECT
.
Вы можете менять набор символов опцией
--default-character-set
при запуске сервера. Наборы символов
доступны в зависимости от опций --with-charset=charset
и
--with-extra-charset=list-of-charset|complex|all
в файле
configure
и файлах конфигурации набора символов, перечисленных в
SHAREDIR/charsets/Index. Подробности в разделе
"2.3.3 Типичные опции configure
".
Если Вы изменяете набор символов при работе MySQL (это может изменять порядок сортировки), Вы должны выполнить myisamchk -r -q на всех таблицах. Иначе Ваши индексы нельзя упорядочивать правильно.
Когда пользователь соединяется с сервером MySQL, тот посылает заданный по умолчанию набор символов пользователю.
Нужно использовать mysql_real_escape_string()
при выходе из
строк для запроса SQL. mysql_real_escape_string()
идентичен
старой функции mysql_escape_string()
, за исключением того, что
требуется дескриптор подключения MYSQL как первый параметр.
Если клиент компилируется с другими путями, чем те, где сервер установлен, и администратор, который конфигурировал MySQL, не включал все наборы символов в двоичный файл MySQL, нужно определить для клиента, где он сможет находить дополнительные наборы символов, а это будет требоваться, если сервер выполняется с другим набором символов.
Можно определять это, включая в файл опции MySQL:
[client] character-sets-dir=/usr/local/mysql/share/mysql/charsets
Где path указывает на то, где сохранены динамические наборы символов MySQL. Можно вынуждать клиента использовать специфический набор символов:
[client] default-character-set=character-set-name
Но обычно этого не требуется.
mysqld
может выдавать сообщения об ошибках на следующих
языках: Czech, Danish, Dutch, English (по умолчанию), Estonian, French,
German, Greek, Hungarian, Italian, Japanese, Korean, Norwegian, Norwegian-ny,
Polish, Portuguese, Romanian, Russian, Slovak, Spanish и Swedish.
Чтобы запустить mysqld
для специфического языка, используйте
параметр --language=lang
или -L lang
. Например:
shell> mysqld --language=swedish
или:
shell> mysqld --language=/usr/local/share/swedish
Обратите внимание, что все имена языка определены в нижнем регистре.
Файлы языка размещены (по умолчанию) в каталоге `mysql_base_dir/share/ЯЗЫК'.
Чтобы модифицировать файл сообщений об ошибках, Вы должны редактировать файл errmsg.txt и выполнить следующую команду, чтобы генерировать новую версию файла errmsg.sys:
shell> comp_err errmsg.txt errmsg.sys
Если Вы обновляете версию MySQL, не забудьте повторить Ваши изменения с новым файлом `errmsg.txt'.
Чтобы добавить другой набор символов к MySQL, используйте следующую процедуру.
Решите, является ли набор простым или сложным. Если набор символов не должен использовать специальную строку, сопоставляющую подпрограммы для сортировки, и не нуждается в поддержке многобайтных символов, он простой. Если требуется любое из этих свойств, набор считается сложным.
Например, latin1
и danish
простые, а вот
big5
или czech
сложные наборы символов.
В следующем разделе я предположил, что Вы называете Ваш набор символов
MYSET
.
Для простого набора символов делают следующее:
ctype
принимает первые 257 слов. После этого массивы
to_lower
, to_upper
и sort_order
берут
по 256 слов каждый.CHARSETS_AVAILABLE
и спискам
COMPILED_CHARSETS
в configure.in
.
Для сложного набора символов делают следующее:
ctype_MYSET
,
to_lower_MYSET
и так далее. Это соответствует массивам в
простом наборе символов.
/* * This comment is parsed by configure to create ctype.c, * so don't change it unless you know what you are doing. * * .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.
to_lower[]
и to_upper[]
представляют собой
простые массивы, которые хранят символы нижнего и верхнего регистров,
соответствующие каждому члену набора символов. Например:
to_lower['A'] should contain 'a' to_upper['a'] should contain 'A'
Массив sort_order[]
представляет собой карту, указывающую,
как символы нужно упорядочивать для целей сортировки и сравнения. Для многих
наборов символов это то же самое, что и to_upper[]
(что
означает: сортировать, не учитывая регистр). MySQL сортирует символы,
основанные на значении sort_order[character]
. Для более сложных
правил сортировки изучите обсуждение сопоставления строк ниже. Подробности в
разделе "4.6.5 Сопоставление строк
".
ctype[]
представляет собой массив разрядных значений, с одним
элементом для одного символа. Обратите внимание, что массивы
to_lower[]
, to_upper[]
и sort_order[]
индексированы символьным значением, но ctype[]
индексирован
символьным значением+1. Это старое наследство, чтобы обработать EOF.
Вы можете находить следующие определения bitmask в m_ctype.h:
#define _U 01 /* Uppercase */ #define _L 02 /* Lowercase */ #define _N 04 /* Numeral (digit) */ #define _S 010 /* Spacing character */ #define _P 020 /* Punctuation */ #define _C 040 /* Control character */ #define _B 0100 /* Blank */ #define _X 0200 /* heXadecimal digit */
Запись в ctype[]
для каждого символа должна быть объединением
применимых значений bitmask, которые описывают символ. Например,
'A'
представляет собой символ верхнего регистра
(_U
) также как шестнадцатеричная цифра (_X
), так
что ctype['A'+1]
должен содержать значение:
_U + _X = 01 + 0200 = 0201
Если правила сортировки для Вашего языка слишком сложны, чтобы быть
обработанными таблицей sort_order[]
, Вы должны использовать
строку, сопоставляющую функции.
Сейчас самая лучшая документация по этому вопросу, это наборы символов, которые уже выполнены. Рассмотрите наборы символов big5, czech, gbk, sjis и tis160 для примеров.
Вы должны определить значение strxfrm_multiply_MYSET=N
в
специальном комментарии наверху файла. N
должен быть установлен
к максимальному коэффициенту роста строки в ходе выполнения
my_strxfrm_MYSET
(это должно быть положительное целое число).
Если нужно добавить поддержку для нового набора символов, который включает многобайтные символы, Вы должны использовать функции многобайтных символов.
Сейчас самая лучшая документация по этому вопросу, это наборы символов,
которые уже выполнены. Рассмотрите наборы символов euc_kr, gb2312, gbk, sjis
и ujis для примеров. Они выполнены в файлах ctype-'charset'.c
в
каталоге strings.
Вы должны определить значение mbmaxlen_MYSET=N
в специальном
комментарии наверху исходного файла. N
должен быть установлен в
размер в байтах самого большого символа в наборе.
Примечания ниже относительно glibc применяются только в ситуации, когда Вы формируете MySQL самостоятельно. Если Вы управляете Linux на x86 машине, в большинстве случаев для Вас намного лучше использовать двоичный дистрибутив. Авторы линкуют свой двоичный дистрибутив с самой лучшей исправленной версией glibc, которую могут найти, и с самыми лучшими параметрами компилятора в попытке сделать его подходящим для сервера с высокой загрузкой. Так что, если Вы читаете текст ниже и находитесь в сомнении относительно того, что Вы должны делать, стоит сначала попробовать применить двоичный дистрибутив, чтобы увидеть, отвечает ли он Вашим потребностяи, и строить свою версию только после того, как Вы обнаружили, что двоичный дистрибутив недостаточно хорош. В этом случае, авторы оценят замечания относительно этого процесса, чтобы в следующий раз лучше сформировать свой двоичный дистрибутив. Для типичного пользователя, даже для установок с большим количеством параллельных подключений и/или при превышении лимита в 2GB, двоичный дистрибутив в большинстве случаев представляет собой самый лучший выбор.
MySQL использует LinuxThreads в Linux. Если Вы используете старую версию
Linux, которая не имеет glibc2
, Вы должны установить
LinuxThreads перед попыткой откомпилировать MySQL. Вы можете получить пакет
LinuxThreads с адреса
http://www.mysql.com/Downloads/Linux.
ОБРАТИТЕ ВНИМАНИЕ: Авторы MySQL видели некоторые странные проблемы с Linux 2.2.14 и MySQL на SMP-системах. Если Вы имеете SMP систему, рекомендуется обновить систему до Linux 2.4 ASAP! Ваша система будет быстрее и более устойчивой после этого!
Обратите внимание, что glibc
Version 2.1.1 и раньше имеет
фатальную ошибку в обработке pthread_mutex_timedwait
, которая
используется, когда Вы вызываете INSERT DELAYED
. Рекомендую Вам
не использовать INSERT DELAYED
до обновления glibc.
Если Вы планируете иметь 1000+ параллельных подключений, Вы должны сделать
некоторые изменения в LinuxThreads, перекомпилировать пакет и повторно
слинковать MySQL с новой версией библиотекой libpthread.a. Увеличьте
PTHREAD_THREADS_MAX
в
sysdeps/unix/sysv/linux/bits/local_lim.h до 4096 и уменьшите
STACK_SIZE
в `linuxthreads/internals.h' до 256 KB.
Пути указаны относительно корня glibc
. Обратите внимание, что
MySQL не будет устойчив с 600-1000 подключениями, если
STACK_SIZE
задан в значение по умолчанию 2 MB.
Если Вы имеете проблему, с которой MySQL не может открывать достаточно файлов или подключений, может быть Вы не конфигурировали Linux, чтобы обработать достаточное число файлов.
В Linux 2.2 и выше Вы можете проверять число распределенных обработчиков:
cat /proc/sys/fs/file-max cat /proc/sys/fs/dquot-max cat /proc/sys/fs/super-max
Если Вы имеете больше, чем 16 MB памяти, Вы должны добавить нечто вроде следующего в Ваш скрипт начальной загрузки (например, /etc/rc/boot.local в SuSE):
echo 65536 > /proc/sys/fs/file-max echo 8192 > /proc/sys/fs/dquot-max echo 1024 > /proc/sys/fs/super-max
Вы можете также выполнять вышеупомянутое из командной строки как root, но в этом случае Ваши старые ограничения будут использоваться в следующий раз, когда система перезагрузится.
Вы должны также добавить в файл /etc/my.cnf:
[safe_mysqld] open-files-limit=8192
Вышеупомянутое должно позволить MySQL создавать до 8192 подключений+файлы.
Константа STACK_SIZE
в LinuxThreads управляет интервалом
стеков потоков в адресном пространстве. Она должна быть достаточно большой,
чтобы имелся участок памяти для стека каждого индивидуального потока, но
достаточно маленькой, чтобы уберечь стек некоторого потока от столкновения с
глобальной переменной mysqld
. К сожалению, Linux-реализация
mmap()
не совсем правильно отображает адреса уже распределенных
регионов при их очистке. Так что безопасность mysqld
, как и
любой другой поточной программы, зависит от поведения кода, который создает
потоки. Выходит, что запросто можно влезть в свои же рабочие данные... Каждая
программа должна самостоятельно следить за тем, куда и что она пишет. В
mysqld
Вы должны предписать это поведение, устанавливая
приемлемое значение для переменной max_connections
.
Если Вы формируете MySQL самостоятельно, и не хотите проблем с внесением
исправлений в LinuxThreads, Вы должны установить max_connections
к значению не выше, чем 500. Это должно быть еще меньше, если Вы имеете
большой буфер ключей, большие таблицы heap или некоторые другие вещи, которые
заставляют mysqld
распределять много памяти, или если Вы
управляете ядром 2.2 с 2GB-заплатой. Если Вы используете RPM version 3.23.25
(или позже) или двоичный дистрибутив, Вы можете безопасно устанавливать
max_connections
в 1500. Для STACK_SIZE
в
LinuxThreads рекомендуются значения в диапазоне 128K и 256K.
Если Вы используете много параллельных подключений, Вы можете страдать от "особенности" в ядре 2.2, которое оштрафует процесс за forking или клонирование в попытке предотвратить нападения типа fork bomb. Это заставит MySQL не масштабироваться как должно бы, когда Вы увеличиваете число параллельных клиентов. На однопроцессорных системах это проявится в очень медленном создании потоков, в результате чего может требоваться длительное время, чтобы подключиться к MySQL (до минуты!), и может требоваться еще столько же на закрытие соединения. Заплата для ядра доступна здесь ( http://www.mysql.com/Downloads/Patches/linux-fork.patch. Эта проблема была исправлена в ядре 2.4.
Авторы проверили MySQL на ядре 2.4 на машине с 2 CPU и нашли, что MySQL
масштабируется теперь НАМНОГО лучше: не имелось фактически никакого
замедления на производительности запросов вплоть до 1000 клиентов, а
коэффициент масштабируемости (отношение максимальной производительности к
производительности с одним пользователем) был 180%. Авторы наблюдали подобные
результаты и на системе с 4 процессорами: фактически никакого замедления,
поскольку число клиентуры увеличивалось до 1000, а коэффициент
масштабируемости составил вообще 300%. Так что для высокой загрузки
SMP-сервера определенно рекомендуется ядро 2.4. Авторы также обнаружили, что
необходимо выполнить процесс mysqld
с самым высоким возможным
приоритетом, чтобы достигнуть максимальной эффективности. Это может быть
выполнено добавлением команды renice -20 $$
в скрипт
safe_mysqld
. Это дало 60% рост производительности с 400
клиентами на 4-процессорной машине.
Имеется другая проблема, которая причиняет значительный вред эффективности MySQL, особенно на SMP-системах. Реализация mutex в LinuxThreads в glibc-2.1 очень плоха для программ со многими потоками, которые используют mutex только в течение короткого времени. На SMP-системе, если Вы компонуете MySQL со стандартным LinuxThreads, удаление процессоров из машины во многих случаях улучшает эффективность MySQL, как ни невероятно. Уже сделали заплату для glibc 2.1.3, linuxthreads-2.1-patch, чтобы исправить это поведение.
С glibc-2.2.2 MySQL version 3.23.36 использует адаптивный
mutex, который намного лучше, чем исправленный glibc-2.1.3.
Однако, что при некоторых условиях, текущий код mutex в
glibc-2.2.2 причиняет вред MySQL эффективности. Возможность
этого может быть уменьшена объявлением renicing для процесса
mysqld
к самому высокому приоритету. Впрочем, есть и заплатка на
http://www.mysql.com/Downloads/Linux/linuxthreads-2.2.2.patch. Вы должны
применить ее в каталоге linuxthreads
командой
patch -p0 </tmp/linuxthreads-2.2.2.patch
. В любом случае,
если Вы компонуете пакет с glibc-2.2.2
, Вы все еще должны
исправить STACK_SIZE
и PTHREAD_THREADS_MAX
.
Лучше всего, чтобы Вы использовали вышеупомянутые заплаты, чтобы
формировать специальную статическую версию libpthread.a
и
использовали ее только для статической компоновки MySQL. Я знаю, что заплаты
безопасны для MySQL и сильно улучшают эффективность, но кто может сказать
хоть что-нибудь относительно других прикладных программ? Если Вы компонуете
другие прикладные программы с исправленной версией библиотеки, или формируете
исправленную общедоступную версию и устанавливаете ее на Вашей системе, за
последствия отвечайте сами.
Если Вы испытываете любые странные проблемы при установке MySQL, или с общим зависанием утилит, вероятно, что они вызваны компилятором или библиотекой. Если дело обстоит так, применение двоичного дистрибутива должно решить эти проблемы.
Одна известная проблема с двоичным дистрибутивом состоит в том, что со
старыми Linux-системами, которые используют libc
(подобно RedHat
4.x или Slackware), Вы получите некоторые с разрешением hostname. Подробности
в разделе "2.6.1.1 Замечания по Linux
для двоичных дистрибутивов".
При использовании LinuxThreads Вы увидите три процесса: один для менеджера LinuxThreads, второй для обработки соединений, а третий для сигналов.
Обратите внимание, что ядро Linux и библиотека LinuxThread могут по умолчанию иметь только 1024 процесса. Это означает, что Вы можете иметь только до 1020 подключений к MySQL на неисправленной системе. Страница http://www.volano.com/linuxnotes.html имеет информацию о том, как обойти это досадное ограничение.
Если Вы видите свалившийся процесс mysqld
с помощью команды
ps
, это обычно означает, что Вы нашли ошибку в MySQL, или Вы
имеете разрушенную таблицу. Подробности в разделе
"8.4.1 Что делать, если MySQL рушится".
Чтобы получить дамп ядра под Linux, если mysqld
завершается с
сигналом SIGSEGV, Вы должны запустить mysqld
с опцией
--core-file
. Обратите внимание, что Вы также, вероятно, должны
поднять размер файла дампа (core file size
), добавляя строку
ulimit -c 1000000
в safe_mysqld
или запуская
safe_mysqld
с опцией --core-file-sizes=1000000
.
Подробности в разделе "4.7.2 safe_mysqld,
обертка вокруг mysqld".
Если Вы компонуете свой клиент MySQL и получаете ошибку:
ld.so.1: ./my: fatal: libmysqlclient.so.4: open failed: No such file or directory
при его выполнении, проблемы можно избежать одним из следующих методов:
-Lpath
): -Wl,r/path-libmysqlclient.so
.
libmysqclient.so
в /usr/lib.
libmysqlclient.so
к системной переменной
LD_RUN_PATH
перед запуском клиента.Если Вы используете компилятор от Fujitsu (fcc/FCC)
Вы будете
иметь некоторые проблемы при компиляции MySQL потому, что заголовочные файлы
Linux ориентированы на gcc
.
Следующая простая строка в configure
должна работать с
fcc/FCC
:
CC=fcc CFLAGS="-O -K fast -K lib -K omitfp -Kpreex -D_GNU_SOURCE -DCONST=const -DNO_STRTOLL_PROTO" CXX=FCC CXXFLAGS="-O -K fast -K lib -K omitfp -K preex --no_exceptions --no_rtti -D_GNU_SOURCE -DCONST=const -Dalloca=__builtin_alloca -DNO_STRTOLL_PROTO' -D_EXTERN_INLINE=static __inline'" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --disable-shared --with-low-memory
MySQL требует как минимум Linux Version 2.0.
ПРЕДУПРЕЖДЕНИЕ: Есть отчеты от некоторых пользователей MySQL, что они имеют серьезные проблемы стабильности MySQL с ядром Linux 2.2.14. Если Вы используете это ядро, Вы должны обновить его до 2.2.19 (или выше) или перейти на ядро 2.4. Если Вы имеете многопроцессорный сервер, то Вы должны серьезно рассмотреть использование 2.4, поскольку это даст Вам значительное увеличение быстродействия.
Двоичный релиз компонуется с опцией -static
, что означает,
что Вы обычно не должны заботиться о том, какую версию библиотек системы Вы
имеете. Вы также не должны устанавливать LinuxThreads. Программа,
скомпонованная с опцией -static
, немного больше, чем динамически
скомпонованная, но также и немного быстрее (на 3-5%). Одна проблема, однако,
состоит в том, что Вы не можете применять определяемые пользователем функции
(UDFs) со статически скомпонованной программой. Если Вы собираетесь писать
или использовать функции UDF (это только для программистов на C или C++), Вы
должны откомпилировать MySQL самостоятельно используя динамические связи.
Если Вы используете libc
-систему (вместо
glibc2
-системы), Вы, вероятно, получите некоторые проблемы с
преобразованием hostname и работой getpwnam()
с двоичным
дистрибутивом. Это потому, что glibc
, к сожалению, зависит от
некоторых внешних библиотек, чтобы работать с hostnames и
getpwent()
, даже когда она компилируется с опцией
-static
. В этом случае Вы, вероятно, получите следующее
сообщение об ошибках, когда Вы выполняете mysql_install_db
:
Sorry, the host 'xxxx' could not be looked up
Или следующую ошибку, когда Вы попробуете выполнять mysqld
с
опцией --user
:
getpwnam: No such file or directory
Вы можете решить эту проблему одним из следующих путей:
tar.gz
) и поставить их
вместо этого дистрибутива.
mysql_install_db --force
. Это не будет выполнять
тест resolveip
в mysql_install_db
. Обратная сторона
в том, что Вы не сможете использовать имена хостов в таблицах предоставления
привилегий. Вы должны взамен использовать IP-адреса (если это не
localhost
). Если Вы используете старый выпуск MySQL, который не
поддерживает --force
, Вы должны удалить тест
resolveip
из mysql_install
ручками.
mysqld
командой su
вместо опции
--user
.Linux-Intel двоичный и RPM-дистрибутивы MySQL сконфигурированы для самого высокого возможного быстродействия.
Поддержка MySQL Perl требует Perl Version 5.004_03 или выше.
На некоторых версиях Linux 2.2 Вы можете получать ошибку Resource
temporarily unavailable
, когда Вы делаете много новых подключений к
серверу mysqld
через TCP/IP.
Проблема состоит в том, что Linux имеет задержку между тем, когда Вы закрываете TCP/IP-порт и тем, когда он фактически будет освобожден системой. Поскольку имеется участок памяти только для конечного числа портов TCP/IP, Вы получите вышеупомянутую ошибку, если Вы пробуете делать слишком много новых TCP/IP-подключений в течение маленького времени подобно тому, когда Вы выполняете эталонный тест MySQL test-connect через TCP/IP.
Единственное известное исправление этой проблемы должно использовать
постоянные подключения в Ваших клиентах или применять сокеты, если сервер и
программы-клиенты работают на одной и той же физической машине. Надеюсь, что
ядро Linux 2.4
эту проблему в будущем снимет.
MySQL требует libc
Version 5.4.12 или выше. Известно, что он
работает с libc
5.4.46. С glibc
Version 2.0.6 и
выше также должен работать. Имелись некоторые проблемы с glibc
RPM из RedHat, так что, если Вы имеете проблемы, проверьте, имеются или нет
любые модификации! RPM glibc
2.0.7-19 и 2.0.7-29, как известно,
работают вполне прилично.
В некоторых старых версиях Linux вызов configure
может
производить ошибку подобно этому:
Syntax error in sched.h. Change _P to __P in the /usr/include/sched.h file. See the Installation chapter in the Reference Manual.
Сделайте то, что говорит сообщение об ошибках и добавьте символ
подчеркивания к макрокоманде _P
, которая имеет только один
символ подчеркивания, затем попробуйте снова.
Вы можете получать некоторые предупреждения при компиляции. Показанные ниже могут игнорироваться:
mysqld.cc -o objs-thread/mysqld.o mysqld.cc: In function `void init_signals()': mysqld.cc:315: warning: assignment of negative value `-1' to `long unsigned int' mysqld.cc: In function `void * signal_hand(void *)': mysqld.cc:346: warning: assignment of negative value `-1' to `long unsigned int'
В Debian GNU/Linux, если Вы хотите, чтобы MySQL запустился автоматически, когда система загружается, сделайте следующее:
shell> cp support-files/mysql.server /etc/init.d/mysql.server shell> /usr/sbin/update-rc.d mysql.server defaults 99
mysql.server
может быть найден в каталоге
share/mysql под каталогом установок MySQL или в каталоге
support-files дерева исходников MySQL.
Если mysqld
всегда падает в дамп при запуске, проблема может
быть в том, что Вы имеете старую /lib/libc.a. Попробуйте
переименовать ее, затем удалить sql/mysqld, выполнить make
install
и запуститься снова. Об этой проблеме было сообщено для
некоторых инсталляций Slackware.
Если Вы получаете следующую ошибку при компоновке mysqld
, это
означает, что Ваша libg++.a не установлена правильно:
/usr/lib/libc.a(putc.o): In function `_IO_putc': putc.o(.text+0x0): multiple definition of `_IO_putc'
Вы можете избежать использования libg++.a запуском
configure
примерно так:
shell> CXX=gcc ./configure
В некоторых реализациях readdir_r()
разрушен. Симптом этого:
SHOW DATABASES
всегда возвращает пустой набор. Это может быть
исправлено удалением HAVE_READDIR_R
из config.h после
настройки, но перед компиляцией.
Некоторые проблемы требуют внесения исправлений в Вашу установку Linux.
Заплата может быть найдена в
http://www.mysql.com/Downloads/patches/Linux-sparc-2.0.30.diff. Эта
заплата для дистрибутива Linux sparclinux-2.0.30.tar.gz, который
является доступным на vger.rutgers.edu
(версия Linux, которая
никогда не была объединена с официальным выпуском 2.0.30). Вы должны также
установить LinuxThreads Version 0.6 или более новую.
MySQL Version 3.23.12 представляет собой первую версию MySQL, которая проверена на Linux-Alpha. Если Вы планируете использовать MySQL на Linux-Alpha, Вы должны гарантировать, что имеете эту версию или более новую.
Когда авторы компилировали стандартный двоичный дистрибутив MySQL, были применены следующие средства: SuSE 6.4, ядро 2.2.13-SMP, компилятор Compaq C (V6.2-504) и Compaq C++ (V6.3-005) на машине on a Compaq DS20 с Alpha EV6.
Вы можете находить вышеупомянутые трансляторы на http://www.support.compaq.com/alpha-tools. Используя эти трансляторы вместо gcc, получается приблизительно на 9-14% лучшая эффективность MySQL.
Обратите внимание, что строка выбора конфигурации оптимизировала двоичный код для текущего CPU. Это означает, что Вы можете использовать двоичный дистрибутив только, если Вы имеете процессор Alpha EV6. Пакет также компилируется статически, чтобы избежать разных библиотечных проблем.
CC=ccc CFLAGS="-fast" CXX=cxx CXXFLAGS="-fast -noexceptions -nortti" ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared
Если Вы хотите использовать egcs, следующая строка настройки пригодится:
CFLAGS="-O3 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --disable-shared
Некоторые известные проблемы при управлении MySQL на Linux-Alpha:
gdb 4.18
. Вы должны загрузить и использовать gdb 5.0!
mysqld
статически при
использовании gcc
, возникающий в результате образ будет падать в
дамп. Другими словами: НЕ используйте
--with-mysqld-ldflags=-all-static
с gcc
!!!MySQL должен работать на MkLinux с самым новым пакетом glibc
(проверен с glibc
2.0.7).
Чтобы получить MySQL, работающий на Qube2 (Linux Mips), Вы нуждаетесь в
самой новой библиотеке glibc
(известно, что
glibc-2.0.7-29C2
работает нормально). Вы должны также
использовать компилятор egcs
C++ (egcs-1.0.2-9
,
gcc 2.95.2
или более новый).
Чтобы компилировать MySQL на Linux Ia64, Вы должны сделать следующее:
Использовать gcc-2.9-final
с такими опциями:
CFLAGS="-O2" CXX=gcc CXXFLAGS="-O2 -felide-constructors -fno-exceptions \ -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler \ --with-mysqld-ldflags=-all-static --disable-shared \ --with-extra-charsets=complex
После make
Вы получите ошибку, что
sql/opt_range.cc
не будет компилироваться (внутренняя ошибка
транслятора). Чтобы исправить это, перейдите в каталог sql и снова введите
make
. Скопируйте строку настройки, но поменяйте в ней -O2 на
-O0. Файл должен теперь компилироваться.
Теперь Вы можете сделать следующее:
cd .. make make_install
и mysqld
должен быть готов выполниться.
На Ia64 клиенты MySQL используют общедоступные библиотеки. Это означает,
что, если Вы устанавливаете двоичный дистрибутив в некоторое другое место, а
не в /usr/local/mysql, Вы должны или изменить
/etc/ld.so.conf или добавить путь к каталогу, где Вы имеете
libmysqlclient.so к системной переменной
LD_LIBRARY_PATH
.
Подробности есть в разделе "8.3.1 Проблемы с компоновкой с библиотекой клиентов MySQL".
Этот раздел описывает установку и использование MySQL в Windows. Эта информация также обеспечивается файлом README, который приходит с дистрибутивом MySQL для Windows.
MySQL использует TCP/IP для связи сервера с клиентом. Из-за этого Вы должны установить TCP/IP на Вашей машине перед запуском MySQL. TCP/IP можно найти на Windows CD-ROM.
Обратите внимание, что, если Вы используете старый выпуск Win95 (например OSR2), вероятно, что Вы имеете старый пакет Winsock! MySQL требует Winsock 2! Вы можете обновить пакет Winsock с http://www.microsoft.com. Win98 имеет новую библиотеку Winsock 2, так что вышеупомянутое на нее не распространяется.
Чтобы запустить сервер mysqld
, Вы должны запустить окно
MS-DOS и напечатать:
C:\> C:\mysql\bin\mysqld
Это запустит mysqld
на заднем плане без окна.
Вы можете уничтожить сервер MySQL, выполняя:
C:\> C:\mysql\bin\mysqladmin -u root shutdown
Обратите внимание, что Win95 и Win98 не поддерживают создание именованных
каналов. В Win95 и Win98, Вы можете только использовать именованные каналы,
чтобы подключиться к удаленной MySQL-системе, работающей под Windows NT.
Сервер MySQL должен также поддерживать именованные каналы, конечно. Например,
использование mysqld-opt
под NT не будет позволять подключения
через именованные каналы. Вы должны использовать mysqld-nt
или
mysqld-max-nt
.
Если mysqld
запускаться не хочет, пожалуйста, проверьте файл
\mysql\data\mysql.err, чтобы увидеть, записал ли сервер там любое
сообщение, чтобы указать причину проблемы. Вы можете также попробовать
запустить сервер с параметром mysqld --standalone
. В этом случае
Вы можете получать некоторую полезную информацию, которая может помочь решить
проблему, на экран.
Можно попробовать запустить mysqld
с --standalone
--debug
. В этом случае mysqld
будет писать журнал
C:\mysqld.trace, который должен содержать причину, почему
mysqld
не запускается. Подробности в разделе
"6.1.2 Создание файлов трассировки
".
Раздел по Win95/Win98 также применим к MySQL под NT/Win2000 со следующими небольшими поправками и особенностями:
Чтобы MySQL мог работать с TCP/IP на NT, Вы должны установить service pack 3 (или выше)!
Для NT/Win2000 имя сервера: mysqld-nt
. Обычно Вы должны
установить MySQL как сервис под NT/Win2000:
C:\> C:\mysql\bin\mysqld-nt --install
или
C:\> C:\mysql\bin\mysqld-max-nt --install
Под Windows NT Вы можете фактически устанавливать любой сервер как сервис,
но только те, чьи имена заканчиваются на -nt.exe
, обеспечивают
поддержку для именованных каналов.
Вы можете запускать и завершать сервис MySQL командами:
C:\> NET START mysql C:\> NET STOP mysql
Обратите внимание, что в этом случае Вы не можете использовать любые
другие параметры для mysqld-nt
!
Вы можете также выполнять mysqld-nt
как автономную программу
на NT, для этого Вы должны запустить mysqld-nt
с параметрами!
Если Вы запускаете mysqld-nt
без параметров на NT,
mysqld-nt
пробует запускать себя как обслуживание с заданными по
умолчанию сервисными параметрами. Если Вы остановили mysqld-nt
,
Вы должны запустить его с помощью NET START mysql
.
Сервис будет установлен с именем MySQL
. После установки он
должен быть запущен через Services Control Manager (SCM) Utility, находящейся
в Control Panel, или через команду NET START MySQL
. Если любые
параметры желательны, они должны быть определены как ``Startup parameters'' в
SCM utility прежде, чем Вы запустите сервис MySQL. После запуска
mysqld-nt
может быть остановлен, используя
mysqladmin
или из SCM, или используя команду NET STOP
MySQL
. Если Вы используете SCM, чтобы остановить
mysqld-nt
, обычно имеется странное сообщение из SCM относительно
mysqld shutdown normally
. Когда сервер выполнен как сервис,
mysqld-nt
не имеет никакого доступа к консоли, так что никакие
сообщения не могут быть замечены.
На NT Вы можете получать следующие сервисные сообщения об ошибках:
Permission Denied | Означает, что не может найти
mysqld-nt.exe . |
Cannot Register | Означает, что путь неправилен. |
Failed to install service. | Означает, что сервис уже установлен, или что Service Control Manager не работает. |
Если Вы имеете проблемы при установке mysqld-nt
как сервиса,
попробуйте запускать его с заданием полного пути:
C:\> C:\mysql\bin\mysqld-nt --install
Если это не работает, Вы можете запустить mysqld-nt
,
устанавливая путь в системном реестре.
Если Вы не хотите запускать mysqld-nt
как сервис, можете
запустить его следующим образом:
C:\> C:\mysql\bin\mysqld-nt --standalone
или
C:\> C:\mysql\bin\mysqld --standalone --debug
Последняя версия дает Вам трассировку отладки в файле C:\mysqld.trace. Подробности в разделе "6.1.2 Создание файлов трассировки ".
MySQL поддерживает TCP/IP на всех платформах Windows и именованные каналы на NT. По умолчанию он должен использовать именованные каналы для локальных подключений на NT и TCP/IP для всех других случаев, если пользователь имеет установленный TCP/IP. Имя хоста определяет, какой протокол используется:
Протокол | |
NULL (none) | Под NT сначала попробовать именованный канал. Если ничего не вышло, использовать TCP/IP. Под Win95/Win98 использовать TCP/IP сразу. |
. | Именованный канал |
localhost | TCP/IP-связь с текущим хостом |
hostname | TCP/IP |
Вы можете вынуждать клиента MySQL использовать именованный канал,
определяя опцию --pipe
или указывая точку (.
) как
имя хоста. Применяйте опцию --socket
, чтобы задать имя канала.
Вы можете проверять, работает или нет MySQL, выполняя следующие команды:
C:\> C:\mysql\bin\mysqlshow C:\> C:\mysql\bin\mysqlshow -u root mysql C:\> C:\mysql\bin\mysqladmin version status proc C:\> C:\mysql\bin\mysql test
Если mysqld
не спешит отвечать на подключения под
Win95/Win98, вероятно, имеется проблема с Вашим DNS. В этом случае запустите
mysqld
с опцией --skip-name-resolve
и используйте
только localhost
и IP-адреса в таблицах предоставления
привилегий MySQL. Вы можете также не использовать DNS при соединении с
mysqld-nt
на NT, задавая параметр --pipe
, чтобы
определить использование именованных каналов. Этот прием работает для
большинства клиентов MySQL.
Имеется две версии инструмента командной строки MySQL:
mysql | Скомпилирован с библиотеками Windows, которые предлагают очень ограниченные возможности редактирования текста. |
mysqlc | Собран с помощью Cygnus GNU compiler и
библиотек, которые предлагают редактирование через readline .
|
Если Вы хотите использовать mysqlc.exe
, Вы должны скопировать
файл C:\mysql\lib\cygwinb19.dll в Ваш системный каталог Windows
(\windows\system).
Заданные по умолчанию привилегии на Windows дают всем локальным
пользователям полные привилегии для доступа ко всем базам данных без того,
чтобы определить пароль. Чтобы сделать MySQL более безопасным, Вы должны
установить пароли для всех пользователей и удалить строку в таблице
mysql.user
, которая имеет значения Host='localhost'
и User=''
.
Вы должны также добавить пароль для пользователя root
.
Следующий пример начинается с удаления анонимного пользователя, который может
использоваться любым, чтобы обратиться к базе данных test
,
а затем устанавливается пароль для root
:
C:\> C:\mysql\bin\mysql mysql mysql> DELETE FROM user WHERE Host='localhost' AND User=''; mysql> QUIT C:\> C:\mysql\bin\mysqladmin reload C:\> C:\mysql\bin\mysqladmin -u root password your_password
После того, как вы установили пароль, если Вы хотите завершить сервер
mysqld
, Вы можете скомандовать:
C:\> mysqladmin --user=root --password=your_password shutdown
Если Вы используете старую shareware-версию MySQL Version 3.21 под
Windows, вышеупомянутая команда будет терпеть неудачу с ошибкой:
parse error near 'SET OPTION password'
. Обновитесь до текущей
версии MySQL, которая свободно доступна.
С текущими версиями MySQL Вы можете легко добавлять новых пользователей и
изменять привилегии командами GRANT
и REVOKE
.
Подробности в разделе "4.3.1 Синтаксис
GRANT
и REVOKE
".
Имеется замечание относительно того, как соединяться, чтобы получить безопасное подключение к удаленному серверу MySQL через SSH (автор: David Carlson, dcarlson@mplcomm.com):
SecureCRT
доступен на
http://www.vandyke.com. Другой вариант:
f-secure
с
http://www.f-secure.com. Вы можете также найти некоторые свободные
клиенты на Google как
http://directory.google.com/Top/Computers/Security/Products_and_Tools/Cryptography/SSH/Clients/Windows.
Крекеры к ним доступны на
http://astalavista.box.sk
Host_Name=yourmysqlserver_URL_or_IP
,
userid=your_userid
для входа на сервер (это далеко не всегда
совпадает с логином/паролем для MySQL).
local_port: 3306
,
remote_host: yourmysqlservername_or_ip
,
remote_port: 3306
) или локальную пересылку (port:
3306
, host: localhost
, remote port: 3306
).
localhost
для хоста сервера MySQL, а не
yourmysqlservername
.Вы должны теперь иметь ODBC-подключение к MySQL, зашифрованное посредством использования протокола SSH.
Начиная с MySQL Version 3.23.16, серверы mysqld-max
и
mysql-max-nt
в дистрибутивах MySQL компилируются с опцией
-DUSE_SYMDIR
. Это позволяет Вам помещать базу данных на другом
диске, добавляя символическую связь с текущим (аналогично тому, как
символические связи работают в Unix).
В Windows Вы делаете символическую связь с базой данных, создавая файл, который содержит путь к каталогу-адресату и пишете его в каталог mysql_data под именем database.sym. Обратите внимание, что символическая связь будет использоваться только, если каталог mysql_data_dir\database не существует.
Например, если каталог данных MySQL C:\mysql\data, и Вы хотите
иметь базу данных foo
, размещенной в D:\data\foo, Вы
должны создать файл C:\mysql\data\foo.sym, который содержит текст
D:\data\foo\
. После того, как это сделано, все таблицы,
созданные в базе данных foo
, будут созданы в каталоге
D:\data\foo.
Обратите внимание, что из-за снижения быстродействия при открытии таблиц,
авторы не включили это дело по умолчанию, даже если Вы компилировали MySQL с
соответствующей поддержкой. Чтобы запустить символические связи, Вы должны
поместить в Ваш файл my.cnf
или my.ini
следующее:
[mysqld] use-symbolic-links
В MySQL 4.0 связи включены по умолчанию. Зато Вы должны использовать опцию
skip-symlink
, если Вы хотите отключить это свойство.
В ваших исходных файлах Вы должны включить windows.h прежде, чем Вы включаете mysql.h:
#if defined(_WIN32) || defined(_WIN64) #include <windows.h> #endif #include <mysql.h>
Вы можете или связывать Ваш код с динамической библиотекой libmysql.lib, которая является только оберткой, чтобы загрузить по требованию libmysql.dll, или скомпоновать со статической библиотекой mysqlclient.lib.
Обратите внимание, что, поскольку библиотеки mysqlclient компилируются как threaded, Вы должны также компилировать Ваш код, как multi-threaded!
MySQL-Windows к настоящему времени доказал свою устойчивость, насколько под этой системой возможно существование устойчивых программ. Эта версия MySQL имеет те же самые свойства, что и соответствующая Unix-версия со следующими исключительными ситуациями:
mysqld
долго под Win95, если Ваш сервер обрабатывает много
подключений! WinNT и Win98 не страдают от этой ошибки.
pread()
и pwrite()
,
чтобы быть способным смешивать INSERT
и SELECT
. В
настоящее время используется mutexes, чтобы эмулировать
pread()
/pwrite()
. Авторы в конечном счете заменят
интерфейс уровня файла на виртуальный интерфейс так, чтобы использовать
readfile()
/writefile()
на NT, чтобы получить
большее быстродействие. Текущая реализация ограничивает число открытых файлов
MySQL 1024, это означает, что Вы не способны выполнить так много параллельных
потоков на NT, как в Unix.
mysqladmin kill
не будет работать на спящем подключении.
mysqladmin shutdown
не может прервать работу сервера, пока
там бездействуют подключения.DROP DATABASE
mysqladmin shutdown
.
LOAD DATA INFILE
или SELECT ... INTO OUTFILE
, Вы
должны задать двойной символ \:
mysql> LOAD DATA INFILE "C:\\tmp\\skr.txt" INTO TABLE skr; mysql> SELECT * INTO OUTFILE 'C:\\tmp\\skr.txt' FROM skr;Альтернативно, используйте имена файлов Unix-стиля с символом `/', но уже с одним:
mysql> LOAD DATA INFILE "C:/tmp/skr.txt" INTO TABLE skr; mysql> SELECT * INTO OUTFILE 'C:/tmp/skr.txt' FROM skr;
Ошибка "Can't open named pipe"
error 2017: can't open named pipe to host: . pipe...Это потому, что финальная версия MySQL по умолчанию использует именованные каналы на NT. Вы можете избегать этой ошибки, используя параметр
--host=localhost
с новой клиентурой MySQL или
создавать файл опций C:\my.cnf, который включает следующее:
[client] host = localhost
Ошибка "Access denied for user"
Access denied for user:
'some-user@unknown' to database 'mysql'
" при обращении к серверу MySQL
на той же самой машине, это означает, что MySQL не может правильно
преобразовать Ваше имя машины. Чтобы это обойти, Вы должны создать файл
\windows\hosts со следующей информацией:
127.0.0.1 localhost
ALTER TABLE
ALTER TABLE
,
таблица блокирована для использования другими потоками. Это потому, что в
Windows Вы не можете удалять файл, который находится в использовании другими
потоками. В будущем планируется найти способ работать без этой проблемы.
DROP TABLE
на таблице, которая находится в
использовании таблицей типа MERGE
, не будет работать
MERGE
делает таблицу скрытой от MySQL. Потому, что
Windows не позволяет Вам удалять файлы, которые являются открытыми, Вы
сначала должны сбросить все таблицы из блока MERGE
(командой
FLUSH TABLES
) или сначала удалить таблицу MERGE
.
Имеются некоторые проблемы для любого, кто мог бы помочь с портированием пакета под Windows:
MYSQL.DLL
. Это
должно включать все из стандартного сервера MySQL, за исключением создания
потоков. Это сделает MySQL намного проще, чтобы использовать в прикладных
программах, которые не нуждаются в истинном протоколе клиент-сервер, и им не
надо обращаться к серверу с других компьютеров.
mysqld
как сервис с опцией
--install
(на NT) было бы хорошо, если бы Вы могли также
добавлять заданные по умолчанию параметры в командной строке.
mysqld
из менеджера задач.
Сейчас для этого надо использовать mysqladmin shutdown
.
readline
под Windows для использования в
инструменте командной строки mysql
.
mysql
,
mysqlshow
, mysqladmin
и mysqldump
).
mysqladmin kill
.
mysqld
всегда запускается с локалью "C". Следует сделать
mysqld
, который использует текущий язык для порядка сортировки.
.DLL
.
Другие специфические для Windows проблемы описаны в файле
README
, который приходит с дистрибутивом MySQL-Windows.
В Solaris Вы можете сталкиваться с проблемой даже прежде, чем Вы получите
распакованный дистрибутив MySQL! Solaris tar
не может
обрабатывать длинные имена файлов, так что Вы можете увидеть такую ошибку,
когда Вы распаковываете MySQL:
x mysql-3.22.12-beta/bench/Results/ATIS-mysql_odbc-NT_4.0-cmp-db2, informix,ms-sql,mysql,oracle,solid,sybase, 0 bytes, 0 tape blocks tar: directory checksum error
В этом случае Вы должны использовать GNU tar
(gtar
), чтобы распаковать дистрибутив. Откомпилированная версия
gtar
для Solaris есть на
http://www.mysql.com/Downloads.
Собственные потоки Sun работают только на Solaris 2.5 и выше. Для Version 2.4 и раньше MySQL автоматически использует MIT-pthreads. Подробности в разделе "2.3.6 Замечания по MIT-pthreads ".
Если Вы получаете следующую ошибку из выбора конфигурации:
checking for restartable system calls... configure: error can not run test programs while cross compiling
Это означает, что Вы имеете что-то неправильное с настройкой компилятора! В этом случае Вы должны его обновить до более свежей версии. Вы можете также решить эту проблему, вставляя следующую строку в файл config.cache:
ac_cv_sys_restartable_syscalls=${ac_cv_sys_restartable_syscalls='no'}
Если Вы используете Solaris на SPARC, рекомендуемый транслятор
gcc
2.95.2. Вы можете найти его на
http://gcc.gnu.org. Обратите внимание, что egcs
1.1.1 и
gcc
2.8.1 не работают надежно на SPARC!
Рекомендуемая строка configure
при использовании
gcc
2.95.2:
CC=gcc CFLAGS="-O3" \ CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti" \ ./configure --prefix=/usr/local/mysql --with-low-memory \ --enable-assembler
Если Вы имеете ultra sparc, Вы можете получить примерно на 4% больше эффективности, добавляя "-mcpu=v8 -Wa,-xarch=v8plusa" к CFLAGS и CXXFLAGS.
Если Вы имеете компилятор Sun Workshop (Fortre) 5.3 (или новее),
Вы можете выполнять configure
так:
CC=cc CFLAGS="-Xa -fast -xO4 -native -xstrconst -mt" \ CXX=CC CXXFLAGS="-noex -xO4 -mt" ./configure --prefix=/usr/local/mysql \ --enable-assembler
В эталонных тестах MySQL получено ускорение на 6% на Ultrasparc при использовании Sun Workshop 5.3 в сравнении с gcc с опцией -mcpu.
Если Вы получаете проблему с fdatasync
или
sched_yield
, Вы можете решить ее добавлением к строке настройки
LIBS=-lrt
.
Следующий параграф относится к компиляторам старше, чем WorkShop 5.3:
Вам, вероятно, также придется редактировать скрипт configure
,
чтобы изменить эту строку:
#if !defined(__STDC__) || __STDC__ != 1
на эту строку:
#if !defined(__STDC__)
Если Вы включаете __STDC__
с опцией -Xc
,
компилятор Sun не может компилировать с файлом заголовка Solaris
pthread.h. Это ошибка Sun.
Если mysqld
выдает сообщение об ошибках, показанное ниже,
значит Вы пробовали компилировать MySQL компилятором Sun без включения опции
процесса с параллельными потоками команд (-mt
):
libc internal error: _rmutex_unlock: rmutex not held
Добавьте -mt
в CFLAGS
и CXXFLAGS
,
после чего попробуйте снова.
Если Вы получаете следующую ошибку при компиляции MySQL с
gcc
, это означает, что Ваш gcc
не конфигурирован
для Вашей версии Solaris:
shell> gcc -O3 -g -O2 -DDBUG_OFF -o thr_alarm ... ./thr_alarm.c: In function `signal_hand': ./thr_alarm.c:556: too many arguments to function `sigwait'
В этом случае надо получить самую новую версию gcc
! По
крайней мере для Solaris 2.5, почти все двоичные версии gcc
имеют старые, непригодные, включаемые файлы, которые разорвут все программы,
использующие потоки (и, возможно, другие программы)!
Solaris не обеспечивает статические версии всех библиотек системы
(libpthreads
и libdl
), так что Вы не можете
компилировать MySQL с опцией --static
. Если Вы попробуете это
сделать, получите ошибку:
ld: fatal: library -ldl: not found или undefined reference to `dlopen' или cannot find -lrt
Если слишком много процессов очень быстро пробуют соединяться с
mysqld
, Вы будете видеть эту ошибку в файле регистрации MySQL:
Error in accept: Protocol error
Вы можете попробовать запускать сервер с опцией --set-variable
back_log=50
для обхода этого. Подробности в разделе
"4.1.1
Опции командной строки mysqld".
Если Вы компонуете собственного MySQL-клиента, можете получить следующую ошибку, когда Вы попробуете выполнить его:
ld.so.1: ./my: fatal: libmysqlclient.so.#: open failed: No such file or directory
Проблемы можно избежать одним из следующих методов:
-Lpath
):
-Wl,r/full-path-to-libmysqlclient.so
.
LD_RUN_PATH
перед запуском клиента.При использовании опции настройки --with-libwrap
, Вы должны
также включить библиотеки, в которых нуждается libwrap.a:
--with-libwrap="/opt/NUtcpwrapper-7.6/lib/libwrap.a -lnsl -lsocket
Если Вы имеете проблемы с выбором конфигурации, пробуя скомпоноваться с
-lz
, и Вы не имеете установленной библиотеки сжатия
zlib
, Вы имеете два варианта действий:
--with-named-z-libs=no
.Если Вы используете gcc и имеете проблемы с загрузкой функций
UDF
в MySQL, попробуйте добавить -lgcc
в строку
компоновки для функций UDF
.
Если Вы хотели бы, чтобы MySQL запускался автоматически, Вы можете скопировать support-files/mysql.server в /etc/init.d и создать символическую связь с именем /etc/rc3.d/S99mysql.server.
Вы можете нормально использовать двоичный код из Solaris 2.6 на Solaris 2.7 и 2.8. Большинство проблем Solaris 2.6 также есть и в Solaris 2.7 и 2.8.
Обратите внимание, что MySQL Version 3.23.4 и выше должен быть способен автоматически обнаружить новые версии Solaris и включить обход проблем!
Solaris 2.7/2.8 имеет некоторые ошибки во включаемых файлах. Вы можете
видеть следующую ошибку, когда Вы используете gcc
:
/usr/include/widec.h:42: warning: `getwc' redefined /usr/include/wchar.h:326: warning: this is the location of the previous definition
Если это происходит, Вы можете сделать следующее, чтобы обойти проблему:
Скопируйте /usr/include/widec.h
в файле
.../lib/gcc-lib/os/gcc-version/include
и поменяйте строку 41 с:
#if !defined(lint) && !defined(__lint) на #if !defined(lint) && !defined(__lint) && !defined(getwc)
Альтернативно, Вы можете непосредственно отредактировать файл
/usr/include/widec.h. В любом случае Вы должен удалить
config.cache и снова запустить скрипт configure
!
Если Вы получаете показанные ниже ошибки при выполнении make
,
это потому, что скрипт configure
не обнаружил файл
curses.h (вероятно, из-за ошибки в /usr/include/widec.h):
In file included from mysql.cc:50: /usr/include/term.h:1060: syntax error before `,' /usr/include/term.h:1081: syntax error before `;'
Решение состоит в том, чтобы сделать одно из следующих действий:
CFLAGS=-DHAVE_CURSES_H
CXXFLAGS=-DHAVE_CURSES_H ./configure
.
#define HAVE_TERM
из файла config.h
и снова выполните make
.Если Вы получаете проблему из-за того, что Ваш компоновщик не может найти
-lz
при попытке компоновки Вашей программы-клиента, вероятно,
что Ваш файл libz.so установлен в /usr/local/lib. Вы можете
исправить эту ситуацию одним из следующих методов:
LD_LIBRARY_PATH
.
--with-named-z-libs=no
.В Solaris 2.8 на x86 mysqld
выпадает в дамп, если Вы
запустите для него strip.
Если Вы используете gcc
или egcs
на Solaris x86,
и Вы испытываете проблемы с дампами при загрузке, Вы должны использовать
следующую команду выбора конфигурации configure
:
CC=gcc CFLAGS="-O3 -fomit-frame-pointer -DHAVE_CURSES_H" \ CXX=gcc \ CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors \ -fno-exceptions -fno-rtti -DHAVE_CURSES_H" \ ./configure --prefix=/usr/local/mysql
Это обходит проблемы с libstdc++
и исключениями в C++.
Если это не помогает, Вы должны компилировать версию для отладки и
выполнять ее с файлом трассировки или под отладчиком gdb
.
Подробности в разделе "6.1.3
Отладка mysqld под gdb".
FreeBSD 3.x рекомендуется для работы MySQL, так как пакет потоков намного больше интегрирован в систему.
Самый простой способ установить пакет состоит в том, чтобы использовать mysql-server и mysql-client, доступные на http://www.freebsd.org.
Использование их дает Вам:
Рекомендуется, чтобы Вы использовали MIT-pthreads на FreeBSD 2.x и местные
потоки на Versions 3 и выше. Возможно выполнять пакет с местными потоками на
некоторых поздних версиях 2.2.x, но Вы можете сталкиваться с проблемами при
закрытии сервера mysqld
.
MySQL Makefile требует для работы GNU make. Если Вы хотите
компилировать MySQL, Вы должны сначала установить GNU make
.
Убедитесь, что имеете правильную установку системы имен. Иначе Вы можете
испытывать задержки сервера имен или сбои при соединении с
mysqld
.
Удостоверьтесь, что запись для localhost
в файле
/etc/hosts правильная (иначе Вы будете иметь проблемы при соединении
с базой данных). Файл /etc/hosts должен начинаться со строки:
127.0.0.1 localhost localhost.your.domain
Если Вы обращаете внимание, что configure
использует
MIT-pthreads, Вы должны прочитать замечания по MIT-pthreads. Подробности в
разделе "2.3.6 Замечания по MIT-pthreads
".
Если Вы получаете ошибку из скрипта make install
, который не
может найти /usr/include/pthreads, configure
не
обнаружил, что Вы нуждаетесь в MIT-pthreads. Это исправляется командой:
shell> rm config.cache shell> ./configure --with-mit-threads
FreeBSD, как известно, имеет очень низкое заданное по умолчанию
ограничение на число дескрипторов файла. Подробности в разделе
"8.2.16 Файл не найден".
Раскомментируйте секцию ulimit -n в safe_mysqld или поднимите ограничения для
пользователя mysqld
в /etc/login.conf (и пересоздайте его с
cap_mkdb /etc/login.conf). Также убедитесь, что Вы устанавливаете
соответствующий класс для этого пользователя в файле паролей, если Вы не
используете значение по умолчанию (скомандуйте chpass mysqld-user-name).
Подробности в разделе "4.7.2 safe_mysqld,
обертка вокруг mysqld".
Если Вы получаете проблемы с текущей датой в MySQL, установка переменной
TZ
, вероятно, поможет. Подробности в разделе
"Приложение 2. Переменные окружения
".
Чтобы получать безопасную и устойчивую систему, Вы должны использовать
только ядра FreeBSD, которые отмечены как -STABLE
.
Чтобы компилировать пакет на NetBSD, Вы нуждаетесь в GNU make
.
Иначе компиляция рухнет, когда make
попробует запустить
lint
на файлах C++.
Данная систем имеет несколько версий, в которых MySQL работает совершенно иначе. Поэтому невозможно дать каких-то конкретных рекомендаций для всех версий данной ОС. Рассмотрим отдельные версии.
В OpenBSD Version 2.5 Вы можете компилировать MySQL с местными потоками со следующими параметрами:
CFLAGS=-pthread CXXFLAGS=-pthread ./configure --with-mit-threads=no
OpenBSD 2.8 имеет ошибку, которая вызывает проблемы с MySQL. Разработчики OpenBSD исправили ошибку, но только с 25 января 2001 новая версия доступна как ``-current''. Признаки этой ошибки: медленный ответ, высоко загружается CPU и ряд сбоев.
Данная систем имеет несколько версий, в которых MySQL работает совершенно иначе. Поэтому невозможно дать каких-то конкретных рекомендаций для всех версий данной ОС. Рассмотрим отдельные версии.
Если Вы получаете следующую ошибку при компиляции MySQL, Ваше значение
ulimit
для размера виртуальной памяти слишком низко:
item_func.h: In method `Item_func_ge::Item_func_ge(const Item_func_ge &)': item_func.h:28: virtual memory exhausted make[2]: *** [item_func.o] Error 1
Попробуйте использовать ulimit -v 80000
и снова выполнить
make
. Если это не работает, и Вы используете bash
,
попробуйте переключиться на csh
или sh
. Некоторые
пользователи BSDI сообщили о проблемах с bash
и
ulimit
.
Если Вы используете gcc
, Вы можете также использовать флаг
--with-low-memory
для configure
, чтобы собрать
sql_yacc.cc.
Если Вы получаете проблемы с текущей датой в MySQL, установка переменной
TZ
, вероятно, поможет. Подробности в разделе
"Приложение 2. Переменные окружения
".
Обновитесь до BSD/OS Version 3.1. Если это невозможно, установите BSDIpatch M300-038.
Используйте следующую команду для конфигурирования MySQL:
shell> env CXX=shlicc++ CC=shlicc2 ./configure \ --prefix=/usr/local/mysql --localstatedir=/var/mysql \ --without-perl \ --with-unix-socket-path=/var/mysql/mysql.sock
Следующее, как правило, работает:
shell> env CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure \ --prefix=/usr/local/mysql \ --with-unix-socket-path=/var/mysql/mysql.sock
Вы можете изменять расположение каталога, если Вы желаете, или только использовать значения по умолчанию, не определяя любые расположения.
Если Вы имеете проблемы с эффективностью при тяжелой загрузке, попробуйте
использовать опцию --skip-thread-priority
для
mysqld
! Это выполнит все потоки с тем же самым приоритетом. На
BSDI Version 3.1 это дает лучшую эффективность (по крайней мере, пока BSDI не
исправит свой планировщик потоков).
Если Вы получаете ошибку "virtual memory exhausted
" при
компиляции, Вы должны попробовать использовать ulimit -v 80000
и
снова выполнить make
. Если это не работает, и Вы используете
bash
, попробуйте переключиться на csh
или
sh
. Некоторые пользователи BSDI сообщили о проблемах с
bash
и ulimit
.
BSDI Version 4.x имеет глюк с потоками. Если Вы хотите использовать MySQL на этой системе, Вы должны установить все связанные с потоками патчи. По крайней мере M400-023 должна быть установлена.
На некоторых версиях BSDI Version 4.x Вы можете получать проблемы с
общедоступными библиотеками. Признаком этого является то, что Вы не можете
выполнять любые программы пользователя, например, mysqladmin
. В
этом случае Вы должны реконфигурировать пакет, чтобы не использовать
общедоступные библиотеки с опцией настройки --disable-shared
.
Некоторые заказчики имели проблемы на BSDI 4.0.1: двоичный дистрибутив
mysqld
через некоторое время не мог открывать таблицы. Это
потому, что некоторая связанная с системой ошибка заставляет
mysqld
изменять текущий каталог без того, чтобы просить об этом!
Либо обновитесь до версии 3.23.34 или более поздней, либо после выполнения
configure
перед запуском make удалите строку
#define HAVE_REALPATH
из config.h
.
Обратите внимание, что вышеупомянутое означает, что Вы не сможете символически связать каталоги баз данных с другим каталогом баз данных или таблицу к другой базе данных на BSDI! (Создание символической связи с другим диском работает нормально).
MySQL должен работать без проблем на Mac OS X Public Beta (Darwin).
Перед попыткой конфигурировать MySQL на Mac OS X server Вы должны сначала установить пакет pthread с http://www.prnet.de/RegEx/mysql.html.
Двоичный дистрибутив для Mac OS X компилируется на Rhapsody 5.5 со
следующей строкой configure
:
CC=gcc CFLAGS="-O2 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O2 -fomit-frame-pointer" ./configure --prefix=/usr/local/mysql "--with-comment=Official MySQL binary" --with-extra-charsets=complex --disable-shared
Вы могли бы также добавлять псевдонимы к файлу ресурсов Вашей оболочки,
чтобы обращаться к утилитам mysql
и mysqladmin
из командной строки:
alias mysql '/usr/local/mysql/bin/mysql' alias mysqladmin '/usr/local/mysql/bin/mysqladmin'
Некоторые из двоичных дистрибутивов MySQL для HP-UX распространяются как базовый файл HP и как файл tar. Чтобы использовать базовый файл, Вы должны работать как минимум с HP-UX 10.x, чтобы иметь доступ к программным инструментальным средствам HP.
HP-версия MySQL компилировалась на сервере HP 9000/8xx под HP-UX 10.20, и использует MIT-pthreads. MySQL Version 3.22.26 и выше может быть собрана с местным пакетом потоков HP.
Другие конфигурации, которые могут работать:
Следующие конфигурации почти наверняка не будут работать:
Чтобы устанавливать дистрибутив, используйте одну из команд ниже, где
/path/to/depot
полное имя пути базового файла:
shell> /usr/sbin/swinstall -s /path/to/depot mysql.full
shell> /usr/sbin/swinstall -s /path/to/depot mysql.server
shell> /usr/sbin/swinstall -s /path/to/depot mysql.client
shell> /usr/sbin/swinstall -s /path/to/depot mysql.developer
Базовые места двоичных модулей и библиотек: /opt/mysql, данных:
/var/opt/mysql. Базовый пакет также создает соответствующие записи в
/etc/init.d и /etc/rc2.d, чтобы запустить сервер
автоматически при начальной загрузке. Очевидно, что для установки надо
работать в системе как root
.
Чтобы устанавливать дистрибутив HP-UX tar.gz, Вы должны иметь копию GNU
tar
.
Имеется пара маленьких проблем при компиляции MySQL на HP-UX.
Рекомендуется, чтобы Вы использовали gcc
вместо местного
компилятора HP-UX потому, что gcc
производит лучший код!
Лучше применить gcc 2.95 на HP-UX. Не используйте высокие флажки оптимизации (подобно -O6), поскольку это не может быть безопасно на HP-UX.
Обратите внимание, что MIT-pthreads не может компилироваться компилятором
HP-UX потому, что он не может компилировать файлы ассемблера
(.S
).
Следующая строка конфигурации должна работать:
CFLAGS="-DHPUX -I/opt/dce/include" CXXFLAGS="-DHPUX -I/opt/dce/include -felide-constructors -fno-exceptions -fno-rtti" CXX=gcc ./configure --with-pthread --with-named-thread-libs='-ldce' --prefix=/usr/local/mysql --disable-shared
Если Вы компилируете gcc
2.95 самостоятельно, Вы НЕ должны
компоновать его с библиотеками DCE (libdce.a
или
libcma.a
) если Вы хотите компилировать MySQL с MIT-pthreads.
Если Вы смешиваете пакеты DCE и MIT-pthreads, Вы получите
mysqld
, с которым Вы не сможете соединяться. Удалите библиотеки
DCE, в то время как Вы компилируете gcc
2.95!
Для HP-UX Version 11.x рекомендуется использовать MySQL Version 3.23.15 или более позднюю.
Из-за некоторых критических ошибок в стандартных библиотеках HP-UX Вы должны установить следующие заплаты перед попыткой выполнить MySQL на HP-UX 11.0:
PHKL_22840 Streams cumulative PHNE_22397 ARPA cumulative
Это решит проблему, что каждый получает EWOULDBLOCK
из
recv()
и EBADF
из accept()
в потоковых
прикладных программах.
Если Вы используете gcc
2.95.1 на неисправленной системе
HP-UX 11.x, Вы получите ошибку:
In file included from /usr/include/unistd.h:11, from ../include/global.h:125, from mysql_priv.h:15, from item.cc:19: /usr/include/sys/unistd.h:184: declaration of C function ... /usr/include/sys/pthread.h:440: previous declaration ... In file included from item.h:306, from mysql_priv.h:158, from item.cc:19:
Проблема в том, что HP-UX, не определяет pthreads_atfork()
.
Это имеет противоречивые прототипы в /usr/include/sys/unistd.h:184 и
/usr/include/sys/pthread.h:440 (в деталях разберемся позже).
Одно решение состоит в том, чтобы копировать /usr/include/sys/unistd.h в mysql/include и отредактировать unistd.h так, чтобы соответствовать определению в pthread.h:
183,184c183,184 < extern int pthread_atfork(void (*prepare)(), void (*parent)(), < void (*child)()); --- > extern int pthread_atfork(void (*prepare)(void), void (*parent)(void), > void (*child)(void));
После того, как это будет сделано, следующая строка выбора конфигурации должна нормально работать:
CFLAGS="-fomit-frame-pointer -O3 -fpic" CXX=gcc CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti -O3" ./configure --prefix=/usr/local/mysql --disable-shared
Имеется некоторая информация, которую пользователь HP-UX Version 11.x предоставил относительно компиляции MySQL оригинальным компилятором HP-UX:x:
Environment: proper compilers. setenv CC cc setenv CXX aCC flags setenv CFLAGS -D_REENTRANT setenv CXXFLAGS -D_REENTRANT setenv CPPFLAGS -D_REENTRANT % aCC -V aCC: HP ANSI C++ B3910B X.03.14.06 % cc -V /tmp/empty.c cpp.ansi: HP92453-01 A.11.02.00 HP C Preprocessor (ANSI) ccom: HP92453-01 A.11.01.00 HP C Compiler cc: "/tmp/empty.c", line 1: warning 501: Empty source file. configuration: ./configure --with-pthread --prefix=/source-control/mysql \ --with-named-thread-libs=-lpthread --with-low-memory added '#define _CTYPE_INCLUDED' to include/m_ctype.h. This symbol is the one defined in HP's /usr/include/ctype.h: /* Don't include std ctype.h when this is included */ #define _CTYPE_H #define __CTYPE_INCLUDED #define _CTYPE_INCLUDED #define _CTYPE_USING /* Don't put names in global namespace. */
-D_REENTRANT
,
чтобы компилятор мог распознать прототип для localtime_r
. Я не
был уверен, где именно компилятор нуждался в этом, так что добавил это
определение ко всем флажкам.
Если Вы получаете следующую ошибку из configure
checking for cc option to accept ANSI C... no configure: error: MySQL requires a ANSI C compiler (and a C++ compiler). Try gcc. See the Installation chapter in the Reference Manual.
Проверьте, что Вы не имеете путь к компилятору K&R перед путем к компиляторам HP-UX C и C++.
Автоматическое обнаружение xlC
отсутствует в Autoconf, так
что команда configure
требует примерно таких определений (этот
пример для компилятора IBM):
export CC="xlc_r -ma -O3 -qstrict -qoptimize=3 -qmaxmem=8192 " export CXX="xlC_r -ma -O3 -qstrict -qoptimize=3 -qmaxmem=8192" export CFLAGS="-I /usr/local/include" export LDLFAGS="-L /usr/local/lib" export CPPFLAGS=$CFLAGS export CXXFLAGS=$CFLAGS ./configure --prefix=/usr/local --localstatedir=/var/mysql \ --sysconfdir=/etc/mysql --sbindir='/usr/local/bin' \ --libexecdir='/usr/local/bin' \ --enable-thread-safe-client --enable-large-files
Выше даны параметры, используемые, чтобы скомпилировать дистрибутив MySQL, который доступен на http://www-frec.bull.com.
Если Вы изменяете -O3
на -O2
в вышеупомянутой
строке выбора конфигурации, Вы должны также удалить опцию
-qstrict
(это ограничение компилятора IBM C).
Если Вы используете gcc
или egcs
, чтобы
откомпилировать MySQL, Вы ДОЛЖНЫ использовать флажок
-fno-exceptions
, поскольку обработка исключительной ситуации в
gcc
/egcs
не поточно-безопасна! Это проверено с
egcs
1.1. Имеются также некоторые известные проблемы с
оригинальным ассемблером IBM, который может генерировать плохой код, когда
используется вместе с gcc.
Автор рекомендует следующую строку configure
для
egcs
и gcc 2.95
на AIX:
CC="gcc -pipe -mcpu=power -Wa,-many" \ CXX="gcc -pipe -mcpu=power -Wa,-many" \ CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti" \ ./configure --prefix=/usr/local/mysql --with-low-memory
Опции -Wa,-many
необходимы для нормального хода процесса. IBM
знает про эту проблему, но не торопится ее исправлять. Я не знаю, требуется
ли -fno-exceptions
с gcc 2.95
, но поскольку MySQL
не использует исключительные ситуации, и вышеупомянутая опция генерирует
более быстрый код, лучше, чтобы Вы всегда использовали эту опцию с
egcs/gcc
.
Если Вы имеете проблему с кодом ассемблера, попробуйте заменить -mcpu=xxx на значение для Вашего cpu. Обычно можно использовать значения power2, power или powerpc, альтернативно Вы могли бы использовать 604 или 604e.
Если Вы не знаете, чем является Ваш центральный процессор, скомандуйте "uname -m", это даст Вам строку, которая напоминает "000514676700", с форматом xxyyyyyymmss, где xx и ss всегда 0, yyyyyy уникальный идентификатор системы, а mm идентификатор CPU Planar. Диаграмма этих значений может быть найдена на http://www.rs6000.ibm.com/doc_link/en_US/a_doc_lib/cmds/aixcmds5/uname.htm. Это даст Вам тип и модель машины, которые Вы можете использовать, чтобы определить, какой центральный процессор Вы имеете.
Если Вы имеете проблемы с сигналами (MySQL неожиданно валится при высокой загрузке) Вы, возможно, нашли ошибку OS с потоками и сигналами. В этом случае Вы можете сообщать, чтобы MySQL не использовал сигналы, конфигурируя его так:
shell> CFLAGS=-DDONT_USE_THR_ALARM CXX=gcc \ CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti -DDONT_USE_THR_ALARM" \ ./configure --prefix=/usr/local/mysql --with-debug --with-low-memory
Это не воздействует на эффективность MySQL, но имеет побочный эффект: Вы
не сможете уничтожать клиентуру, которая является бездействующей, с помощью
mysqladmin kill
или mysqladmin shutdown
.
На некоторых версиях AIX, компонующихся с libbind.a
вызов
getservbyname
создает дамп ядра. Это ошибка AIX. Она должна быть
сообщена в фирму IBM.
Для AIX 4.2.1 и gcc Вы должны сделать следующие изменения:
После конфигурирования, отредактируйте config.h и include/my_config.h и смените строку
#define HAVE_SNPRINTF 1
на
#undef HAVE_SNPRINTF
В mysqld.cc Вы должны добавить прототип для initgoups.
#ifdef _AIX41 extern "C" int initgroups(const char *,int); #endif
В SunOS 4 пакет MIT-pthreads необходим, чтобы компилировать MySQL, что в
свою очередь означает, что Вы будете нуждаться в GNU make
.
Некоторые системы SunOS 4 имеют проблемы с динамическими библиотеками и
libtool
. Вы можете использовать следующую строку для
configure
, чтобы избежать этой проблемы:
shell> ./configure --disable-shared --with-mysqld-ldflags=-all-static
При компиляции readline
Вы можете получить предупреждения
относительно дубликата определений. Они могут спокойно игнорироваться.
При компиляции mysqld
будет предупреждение implicit
declaration of function
. Можно игнорировать.
Если Вы используете egcs 1.1.2 на Digital Unix, Вы должны обновиться до gcc 2.95.2, поскольку egcs в DEC имеет некоторые серьезные ошибки!
При компиляции поточных программ под Digital Unix документация рекомендует
использовать опцию -pthread
для cc
и
cxx
и библиотеки -lmach -lexc
(в дополнение к
-lpthread
). Вы должны выполнить configure
так:
CC="cc -pthread" CXX="cxx -pthread -O" \ ./configure --with-named-thread-libs="-lpthread -lmach -lexc -lc"
При построении mysqld
Вы можете видеть пару предупреждений
подобно вот этому:
mysqld.cc: In function void handle_connections()': mysqld.cc:626: passing long unsigned int *' as argument 3 of accept(int,sockadddr *, int *)'
Вы можете безопасно игнорировать эти предупреждения. Они происходят
потому, что скрипт configure
может обнаруживать только ошибки,
но не предупреждения.
Если Вы запускаете сервер непосредственно с командной строки, Вы можете
иметь проблемы с этим, когда Вы регистрируете извне, по сети: Ваши ожидающие
обработки процессы получают сигнал SIGHUP
. Если это так,
попробуйте запускать сервер таким образом:
shell> nohup mysqld [options] &
Вызов nohup
заставляет команду игнорировать любой сигнал
SIGHUP
, посланный с терминала. Альтернативно, запустите сервер
через safe_mysqld
, который вызывает mysqld
через
nohup
. Подробности в разделе "
4.7.2 safe_mysqld, обертка вокруг mysqld".
Если Вы получаете проблему при компиляции mysys/get_opt.c
,
удалите строку #define _NO_PROTO
из начала этого файла!
Если Вы используете компилятор Compac's CC compiler, следующая строка выбора конфигурации должна работать:
CC="cc -pthread" CFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed all -arch host" CXX="cxx -pthread" CXXFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed all -arch host" export CC CFLAGS CXX CXXFLAGS ./configure --prefix=/usr/local/mysql --with-low-memory \ --enable-large-files --enable-shared=yes \ --with-named-thread-libs="-lpthread -lmach -lexc -lc" gnumake
Если Вы получаете проблему с libtool при компиляции с общедоступными
библиотеками, то при компоновке mysql
Вы способны обойти ее:
cd mysql /bin/sh ../libtool --mode=link cxx -pthread -O3 -DDBUG_OFF \ -O4 -ansi_alias -ansi_args -fast -inline speed \ -speculate all \ -arch host -DUNDEF_HAVE_GETHOSTBYNAME_R \ -o mysql mysql.o readline.o sql_string.o completion_hash.o \ ../readline/libreadline.a -lcurses \ ../libmysql/.libs/libmysqlclient.so -lm cd .. gnumake gnumake install scripts/mysql_install_db
Если Вы имеете проблемы при компиляции и имеете установленные DEC
CC
и gcc
, попробуйте
так запустить configure
:
CC=cc CFLAGS=-O CXX=gcc CXXFLAGS=-O3 \ ./configure --prefix=/usr/local/mysql
Если Вы получаете проблемы с файлом c_asm.h, Вы можете создать и использовать пустой файл c_asm.h:
touch include/c_asm.h CC=gcc CFLAGS=-I./include \ CXX=gcc CXXFLAGS=-O3 \ ./configure --prefix=/usr/local/mysql
Обратите внимание, что следующие проблемы с программой ld
могут быть исправлены загрузкой последнего комплекта заплаток DEC (Compaq) с
http://ftp.support.compaq.com/public/unix.
На OSF1 V4.0D с компилятором "DEC C V5.6-071 on Digital Unix V4.0 (Rev.
878)" транслятор имел некоторое странное поведение (неопределенные символы
asm
). /bin/ld
также неправильный (проблемы с
ошибкой _exit undefined
при компоновке mysqld
). На
этой системе удалось собрать MySQL со следующей строкой для вызова
configure
, после замены /bin/ld
на
версию из OSF 4.0C:
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
С Digital compiler "C++ V6.1-029" следующее должно работать:
CC=cc -pthread CFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed \ -speculate all -arch host CXX=cxx -pthread CXXFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed -speculate all \ -arch host -noexceptions -nortti export CC CFLAGS CXX CXXFLAGS ./configure --prefix=/usr/mysql/mysql --with-mysqld-ldflags=-all-static \ --disable-shared --with-named-thread-libs="-lmach -lexc -lc"
В некоторых версиях OSF1 функция alloca()
неправильная.
Исправьте это, удаляя строку в файле config.h, которая определяет
'HAVE_ALLOCA'
.
Функция alloca()
также может иметь неправильный прототип в
/usr/include/alloca.h
. Предупреждение об этом можно игнорировать.
configure
автоматически использует следующие библиотеки
потоков: --with-named-thread-libs="-lpthread -lmach -lexc -lc"
.
При использовании gcc
, Вы можете также попробовать такой
запуск скрипта configure
:
shell> CFLAGS=-D_PTHREAD_USE_D4 CXX=gcc CXXFLAGS=-O3 ./configure ....
Если Вы имеете проблемы с сигналами (MySQL неожиданно валится при высокой загрузке) Вы, возможно, нашли ошибку OS с потоками и сигналами. В этом случае Вы можете сообщать, чтобы MySQL не использовал сигналы, конфигурируя его так:
shell> CFLAGS=-DDONT_USE_THR_ALARM \ CXXFLAGS=-DDONT_USE_THR_ALARM \ ./configure ...
Это не воздействует на эффективность MySQL, но имеет побочный эффект: Вы
не сможете уничтожать клиентуру, которая является бездействующей, с помощью
mysqladmin kill
или mysqladmin shutdown
.
С gcc
2.95.2 Вы, вероятно, столкнетесь со следующей ошибкой:
sql_acl.cc:1456: Internal compiler error in `scan_region', at except.c:2566 Please submit a full bug report.
Чтобы это исправить, Вы должны изменить текущий каталог на
sql
и выдать последнюю строку запуска gcc
, заменив
в ней -O3
на -O0
(или добавив -O0
сразу после gcc
, если Вы не имеете опции -O
). После
того, как это будет выполнено, Вы можете перейти в прежний каталог и снова
выполнить оттуда make
.
Если Вы используете Irix Version 6.5.3 или более новую,
mysqld
будет способен создать только, если Вы выполняете его как
пользователь с привилегиями CAP_SCHED_MGT
(подобно
root
) или даете серверу mysqld
эту привилегию с
следующей командой оболочки:
shell> chcap "CAP_SCHED_MGT+epi" /opt/mysql/libexec/mysqld
Вам, вероятно, придется разопределить некоторые вещи в config.h
после выполнения configure
, но перед компиляцией.
В некоторых реализациях Irix функция alloca()
ошибочна. Если
сервер mysqld
рушится на некоторых инструкциях
SELECT
, удалите из config.h строки, которые определяют
HAVE_ALLOC
и HAVE_ALLOCA_H
. Если mysqladmin
create
не работает, удалите из config.h строку, определяющую
HAVE_READDIR_R
. Вам, вероятно, придется также удалить строку
HAVE_TERM_H
.
SGI рекомендует, чтобы Вы установили все заплаты с этой страницы как набор: http://support.sgi.com/surfzone/patches/patchset/6.2_indigo.rps.html.
Как минимум, Вы должны установить последние kernel rollup,
rld
и библиотеку libc
.
Вы определенно нуждаетесь во всех заплатах POSIX на этой странице для поддержки потоков pthreads: http://support.sgi.com/surfzone/patches/patchset/6.2_posix.rps.html.
Если Вы получаете нечто вроде следующей ошибки при компиляции mysql.cc:
"/usr/include/curses.h", line 82: error(1084): invalid combination of type
Введите следующее в верхнем каталоге дерева исходников MySQL:
shell> extra/replace bool curses_bool < /usr/include/curses.h > include/curses.h shell> make
Также имелись отчеты о проблемах с планировщиком. Если только один поток запущен, все работает медленно. Избегайте этого, запуская другого пользователя. Это может привести к увеличению быстродействия выполнения в 2-10 раз с этого времени для другого потока. Это плохо понятная проблема с потоками Irix. Вам, вероятно, придется импровизировать, чтобы найти оптимальное решение, пока это не может быть исправлено радикально.
Если Вы компилируете с gcc
, Вы можете использовать следующий
вызов команды configure
:
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --enable-thread-safe-client \ --with-named-thread-libs=-lpthread
На Irix 6.5.11 с собственным компилятором Irix C и C++ ver. 7.3.1.2, следующее, как сообщают, работает:
CC=cc CXX=CC CFLAGS='-O3 -n32 -TARG:platform=IP22 -I/usr/local/include \ -L/usr/local/lib' CXXFLAGS='-O3 -n32 -TARG:platform=IP22 \ -I/usr/local/include -L/usr/local/lib' ./configure --prefix=/usr/local/mysql --with-berkeley-db --with-innodb \ --with-libwrap=/usr/local \ --with-named-curses-libs=/usr/local/lib/libncurses.a
Текущий порт проверен только на системах sco3.2v5.0.4 и sco3.2v5.0.5. Также имелось много прогресса на порте к sco 3.2v4.2.
Сейчас рекомендуемый транслятор на OpenServer: 2.95.2. С ним Вы должны компилировать MySQL так:
CC=gcc CXX=gcc ./configure ... (options)
gcc
2.7.2 в Skunkware 97
не имеет GNU as
. Вы можете также использовать egcs
1.1.2 или более новый с
http://www.egcs.com. Если Вы используете egcs
1.1.2, Вы
должны выполнить следующую команду:
shell> cp -p /usr/include/pthread/stdtypes.h \ /usr/local/lib/gcc-lib/i386-pc-sco3.2v5.0.5/egcs-2.91.66/include/pthread/
./configure
в каталоге threads/src и
выберите опцию SCO OpenServer. Эта команда скопирует Makefile.SCO5 в
Makefile.
make
.
cd
в каталог thread/src и
выполните оттуда make install
.make
при создании MySQL.
safe_mysqld
как root, Вы, вероятно,
получите только значение по умолчанию 110 открытых файлов на процесс. Сервер
mysqld
будет писать замечание относительно этого в журнал.
configure
должна работать:
shell> ./configure --prefix=/usr/local/mysql --disable-shared
configure
должна работать:
shell> CFLAGS="-D_XOPEN_XPG4" CXX=gcc CXXFLAGS="-D_XOPEN_XPG4" \ ./configure --prefix=/usr/local/mysql \ --with-named-thread-libs="-lgthreads -lsocket -lgen \ -lgthreads" --with-named-curses-libs="-lcurses"Вы можете получать некоторые проблемы с включаемыми файлами. В этом случае Вы можете найти новые SCO-специфичные включаемые файлы по адресу http://www.mysql.com/Downloads/SCO/SCO-3.2v4.2-includes.tar.gz. Вы должны распаковать этот файл в каталог include дерева исходников MySQL.
Замечания для разработчиков под SCO:
mysqld
с -lgthreads -lsocket -lgthreads
.
malloc
. Если Вы
сталкиваетесь с проблемами с использованием памяти, удостоверьтесь, что
gmalloc.o включен в libgthreads.a и в
libgthreads.so.
read()
, write()
, getmsg()
,
connect()
, accept()
, select()
и
wait()
.Если Вы хотите устанавливать DBI на SCO, Вы должны отредактировать Makefile DBI-xxx и в каждом подкаталоге.
Обратите внимание на следующие изменения для gcc 2.95.2 или новее:
OLD: NEW: CC = cc CC = gcc CCCDLFLAGS = -KPIC -W1,-Bexport CCCDLFLAGS = -fpic CCDLFLAGS = -wl,-Bexport CCDLFLAGS = LD = ld LD = gcc -G -fpic LDDLFLAGS = -G -L/usr/local/lib LDDLFLAGS = -L/usr/local/lib LDFLAGS = -belf -L/usr/local/lib LDFLAGS = -L/usr/local/lib LD = ld LD = gcc -G -fpic OPTIMISE = -Od OPTIMISE = -O1 OLD: CCCFLAGS = -belf -dy -w0 -U M_XENIX -DPERL_SCO5 -I/usr/local/include NEW: CCFLAGS = -U M_XENIX -DPERL_SCO5 -I/usr/local/include
Это потому, что Perl dynaloader не будет загружать
DBI
-модули, если они компилировались с icc
или
cc
.
Perl работает лучше всего, когда компилируется с cc
.
Вы должны использовать версию MySQL, по крайней мере не ниже Version 3.22.13 потому, что та версия исправляет некоторые проблемы с Unixware.
Я компилировал MySQL следующей
командой configure
в Unixware 7.0.1:
CC=cc CXX=CC ./configure --prefix=/usr/local/mysql
Если Вы хотите использовать gcc
, Вы должны использовать
gcc
2.95.2 или более новый.
MySQL использует несколько открытых файлов. Из-за этого, Вы должны добавить нечто вроде следующего к Вашему файлу CONFIG.SYS:
SET EMXOPT=-c -n -h1024
Если Вы не сделаете это, Вы, вероятно, столкнетесь со следующей ошибкой:
File 'xxxx' not found (Errcode: 24)
При использовании с OS/2 Warp 3, требуется FixPack 29 или выше. Для OS/2 Warp 4 нужен FixPack 4 или выше. Это требование библиотеки Pthreads. MySQL должен быть установлен в раздел, который поддерживает длинные имена файлов, типа HPFS или FAT32.
Скрипт INSTALL.CMD должен быть выполнен собственным интерпретатором OS/2 CMD.EXE, и не может работать с оболочками замены, типа 4OS2.EXE.
Скрипт scripts/mysql-install-db был переименован. Он теперь назван install.cmd и является REXX-скриптом, который установит заданные по умолчанию параметры настройки защиты MySQL и создаст пиктограммы WorkPlace Shell для MySQL.
Динамическая поддержка модулей компилируется, но пока не полностью проверена. Динамические модули должны компилироваться, используя библиотеку поддержки Pthreads run-time library.
gcc -Zdll -Zmt -Zcrtdll=pthrdrtl -I../include -I../regex -I.. \ -o example udf_example.cc -L../lib -lmysqlclient udf_example.def mv example.dll example.udf
Обратите внимание: из-за ограничений OS/2, имена модулей
UDF не должны превышать 8 символов. Модули сохранены в каталоге
/mysql2/udf. Скрипт safe-mysqld.cmd
поместит этот
каталог в системную переменную BEGINLIBPATH
. При использовании
UDF-модуля, определенные расширения игнорируются, должны быть .udf.
Например, в Unix общедоступный модуль мог бы быть именован как
example.so, и Вы загрузите функцию из него примерно так:
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "example.so";
В OS/2 модуль будет именован как example.udf, но Вы не будете определять расширение модуля:
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "example";
Разработчики пакета очень заинтересованы получением MySQL, чтобы работать на BeOS, но, к сожалению, не имеют человека, который знает BeOS или имеет время, чтобы сделать порт.
Разработчики пакета заинтересованы нахождением кого-то, чтобы сделать порт, и помогут им с любыми техническими вопросами, которые они могут иметь при выполнении порта.
Они уже предварительно говорили с некоторыми BeOS-разработчиками, которые сказали, что MySQL на 80%, перенесен на BeOS, но так и не получили известий от них вовремя.
Разработчики пакета очень заинтересованы получением MySQL, чтобы работать на Netware, но, к сожалению, не имеют человека, который знает Netware или имеет время, чтобы сделать порт.
Разработчики пакета заинтересованы нахождением кого-то, чтобы сделать порт, и помогут им с любыми техническими вопросами, которые они могут иметь при выполнении порта.
MySQL имеет несколько различных журналов (протоколов), которые могут
помочь Вам выяснить то, что происходит внутри mysqld
:
Файл регистрации ошибок | Проблемы со стартом, работой или
остановкой mysqld . |
Файл регистрации isam | Регистрирует все изменения для таблиц системы ISAM. Использован только для отладки isam-кода. |
Файл регистрации запросов | Регистрирует все установленные подключения и выполненные запросы. |
Файл регистрации модификаций | Сохраняет все инструкции, которые изменяют данные. |
Двоичный файл регистрации | Сохраняет все инструкции, которые изменяет что-либо. Использован также для репликации. |
Медленный файл регистрации | Сохраняет все запросы, которые
заняли времени больше, чем long_query_time для своего выполнения
или не использовали индексы. |
Все файлы регистрации могут быть найдены в каталоге данных
mysqld
. Вы можете вынуждать mysqld
вновь открывать
журналы (или переключаться на новые журналы), выполняя команду FLUSH
LOGS
. Подробности в разделе "4.5.3
Синтаксис FLUSH
".
Сервер mysqld
пишет все ошибки на stderr, который скрипт
safe_mysqld
переназначает в файл с именем
'hostname'.err
. В Windows mysqld
пишет ошибки в
файл с именем \mysql\data\mysql.err.
Этот протокол содержит информацию, указывающую, когда mysqld
был запущен и остановлен, а также любые критические ошибки. Если
mysqld
неожиданно свалился, и safe_mysqld
должен
перезапустить mysqld
, safe_mysqld
оставит строку
restarted mysqld
в этом файле. Этот файл регистрации также
сохраняет предупреждение, если mysqld
обращает внимание на
таблицу, которая должна быть автоматически проверена или восстановлена.
На некоторых операционных системах, файл регистрации ошибок будет
содержать трассировку стека для случая падения mysqld
. Это может
использоваться, чтобы выяснить, где и почему свалился mysqld
.
Подробности в разделе "6.1.4
Использование трассировки стека".
Если Вы хотите знать, что происходит внутри mysqld
, Вы должны
запустить его с опцией --log[=file]
. Это регистрирует все
подключения и запросы в журнале (по умолчанию `'hostname'.log').
Этот файл регистрации может быть очень полезен, когда Вы подозреваете ошибку
в коде клиента и хотите знать точно, что именно ему передавал
mysqld
.
По умолчанию скрипт mysql.server
запускает сервер MySQL с
опцией -l
. Если Вы нуждаетесь в лучшей эффективности, когда
запускаете MySQL в промышленной среде, Вы можете удалить опцию
-l
из mysql.server
или заменить ее на
--log-binary
.
Записи в этом файле регистрации записываются в порядке получения запросов
mysqld
. Это может отличаться от порядка выполнения инструкций.
Этим данный журнал отличается от файла регистрации модификаций и двоичного
файла регистрации, которые пишутся после того, как запрос выполнен, но
прежде, чем любые блокировки будут сняты.
ОБРАТИТЕ ВНИМАНИЕ: Файл регистрации модификаций заменен двоичным файлом регистрации. Подробности в разделе "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.10 Репликация в MySQL".
При запуске с параметром --log-bin[=file_name]
mysqld
пишет журнал, содержащий все команды SQL, которые меняли
данные в базе. Если имя файла не задано, используется имя хоста с суффиксом
-bin
. Если имя файла задано, но не содержит путь, файл будет
записан в каталог данных.
Вы можете использовать следующие параметры для mysqld
, чтобы
воздействовать на то, что регистрируется в двоичном файле регистрации:
binlog-do-db=database_name |
Сообщает, что следует регистрировать модификации для определенной базы данных
и исключать все другие, не упомянутые явно (например:
binlog-do-db=some_database ). |
binlog-ignore-db=database_name |
Сообщает, что модификации данной базы данных не должны регистрироваться в
двоичном файле регистрации (например:
binlog-ignore-db=some_database ). |
К имени двоичного файла регистрации mysqld
конкатенирует
расширение, которое является номером, растущим каждый раз, когда Вы
выполняете команды mysqladmin refresh
,
mysqladmin flush-logs
, FLUSH LOGS
или
перезапускаете весь сервер.
Чтобы знать, которые двоичные журналы использовались, mysqld
также создает двоичный индексный файл регистрации, который содержит имена
всех используемых двоичных журналов. По умолчанию он имеет то же самое имя,
что и двоичный журнал, но с расширением '.index'
. Вы можете
изменять имя двоичного индексного файла опцией
--log-bin-index=[filename]
.
Если Вы используете репликацию, то не должны удалять старые двоичные
журналы, пока не будете уверены, что никакой подчиненный сервер не будет
когда-либо их использовать. Один способ сделать это состоит в том, чтобы
использовать команду mysqladmin flush-logs
один раз в день и
затем удалять любые файлы регистрации, которые старше трех дней.
Вы можете исследовать двоичный журнал командой mysqlbinlog
.
Например, Вы можете обновить сервер MySQL из двоичного файла регистрации
следующим образом:
mysqlbinlog log-file | mysql -h server_name
Вы можете также использовать программу mysqlbinlog
, чтобы
читать двоичный файл регистрации непосредственно с удаленного сервера MySQL!
Вызов mysqlbinlog --help
даст Вам большее количество
информации того, как использовать эту программу.
Если Вы используете BEGIN [WORK]
или
SET AUTOCOMMIT=0
, то Вы должны использовать двоичный файл
регистрации MySQL для целей резервирования вместо старого формата файла
регистрации модификаций.
Двоичная регистрация будет выполнена немедленно после того, как запрос завершится, но прежде, чем любые блокировки будут сняты. Это гарантирует, что файл регистрации будет отражать порядок выполнения команд.
Все модификации (UPDATE
, DELETE
или
INSERT
), которые изменяют транзакционные таблицы (подобные
таблицам BDB), кэшируются до COMMIT
. Любые модификации в
нетранзакционных таблицах будут сохранены в двоичном файле регистрации сразу.
Каждый процесс будет на старте распределять буфер
binlog_cache_size
, чтобы буферизовать запросы. Если запрос
больше, чем этот буфер, процесс откроет временный файл, чтобы обработать
большой кэш. Временный файл будет удален, когда процесс заканчится.
Параметр max_binlog_cache_size
может использоваться, чтобы
ограничить максимальный размер буфера, используемого, чтобы кэшировать запрос
для нескольких транзакций.
Если Вы используете модификацию или двоичный файл регистрации,
параллельные вставки не будут работать вместе с
CREATE ... INSERT
и INSERT ... SELECT
. Это должно
гарантировать, что Вы можете пересоздать точную копию Ваших таблиц, применяя
регистрацию к резервной копии.
При запуске с опцией --log-slow-queries[=file_name]
mysqld
пишет журнал, содержащий все команды SQL, которые
обрабатывались дольше, чем long_query_time
. Время, которое
понадобилось, чтобы получить начальные блокировки таблицы, не учитывается как
время выполнения запроса.
Медленный файл регистрации запроса регистрируется после того, как запрос выполнен, и после того, как все блокировки были сняты. Это может отличаться от порядка выполнения инструкций.
Если никакое имя файла не задано, используется имя хоста с окончанием
-slow.log
. Если имя файла задано, но не содержит путь, файл
будет записан в каталоге данных.
Медленный файл регистрации запроса может использоваться, чтобы найти
запросы, которые берут длительное время, и таким образом являются кандидатами
на оптимизацию. Имея дело с большим файлом регистрации, который может стать
трудной задачей, Вы можете пропустить его через программу
mysqldumpslow
, чтобы получать резюме запросов, которые
появляются в файле регистрации.
Если Вы используете --log-long-format
, также будут выведены
запросы, не использующие индексы. Подробности в разделе
"4.1.1 Параметры командной строки
mysqld".
MySQLимеет много журналов, которые весьма облегчают работу. Однако, их нужно время от времени чистить, чтобы гарантировать, что файлы регистрации не занимают слишком много дискового пространства.
При использовании MySQL с журналами Вы будете время от времени удалять/резервировать старые журналы и сообщать, чтобы MySQL начал регистрацию событий в новых файлах. Подробности есть в разделе "4.4.1 Обновление протоколов ".
В Linux (дистрибутив Redhat
) Вы можете для этого использовать
скрипт 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
Таблицы MERGE
представляют собой новшество MySQL Version
3.23.25. Их код пока находится в отладке, но в основном уже работает.
Таблица MERGE
представляет собой совокупность идентичных
таблиц MyISAM
, которые могут использоваться как одна. Вы можете
выполнять только операции SELECT
, DELETE
и
UPDATE
над совокупностью таблиц. Если Вы выполняете
DROP
для таблицы MERGE
, удаляется только
определение для таблицы MERGE
.
Под идентичными таблицами понимается, что все таблицы созданы с идентичной
информацией о ключах и столбцах. Вы не можете помещать MERGE поверх таблиц,
где столбцы упакованы по-разному, не имеют точно те же самые столбцы, или
имеют ключи в ином порядке. Некоторые из таблиц могут быть сжаты
myisampack
.
Когда Вы создаете таблицу MERGE
, Вы получите файл
.frm
определения таблицы и файл .MRG
списка таблиц.
Файл .MRG
содержит только список индексных файлов (файлы
.MYI
), которые должны использоваться как один. Все используемые
таблицы должны быть в той же самой базе данных, что и таблица типа
MERGE
.
Вы должны иметь привилегии SELECT
, UPDATE
и
DELETE
на таблицах, которые Вы отображаете на таблицу
MERGE
.
MERGE
-таблицы, могут помогать Вам решить следующие проблемы:
myisampack
, а затем создавать
MERGE
, чтобы использовать их как один.
MERGE
-таблица на этом
могла бы быть намного быстрее, чем использование большой таблицы. Вы можете,
конечно, также использовать RAID для получения аналогичного результата.
MERGE
с перекрываниями.
MERGE
, чем огромную базу данных.
MERGE
использует индексы индивидуальных таблиц. Не требуется поддерживать общий
индекс. Это делает такие таблицы ОЧЕНЬ быстрыми. Обратите внимание, что Вы
должны определить описания ключа, когда Вы создаете таблицу
MERGE
!
MERGE
. Это намного быстрее и сохранит много места на диске.
Недостатки таблиц MERGE
:
INSERT
на таблицах
MERGE
, поскольку MySQL не может знать, в которую из таблиц Вы
должны вставить строку.
MyISAM
для
таблицы MERGE
.
MERGE
используют большое количество описателей
файла. Если Вы применяете MERGE, чтобы отобразить более,
чем 10 таблиц, и 10 пользователей применяют это, Вам понадобится 10*10+10=110
описателей (дескрипторов) файла (10 файлов данных для 10 пользователей и еще
10 для общедоступных индексных файлов).
MERGE
будет должен выдать чтение на всех основных таблицах,
чтобы проверить, которая наиболее близко соответствует данному ключу. Если Вы
затем делаете 'read-next', драйвер таблицы будет должен искать буфера чтений,
чтобы найти следующий ключ. Только, когда один буфер ключей будет исчерпан,
драйвер начнет читать следующий блок. Это делает ключи MERGE
намного медленнее при поиске eq_ref
, но не намного медленнее при
поиске ref
.
DROP TABLE
, ALTER
TABLE
или DELETE FROM table_name
без предложения
WHERE
на любой таблицы, которая отображена на открытую таблицу
MERGE
. Если Вы это сделаете, таблица MERGE
все еще
может обратиться к первоначальной таблице, и Вы получите совершенно
непредвиденные результаты.Следующий пример показывает, как использовать таблицы MERGE
:
CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, message CHAR(20)); CREATE TABLE t2 (a INT AUTO_INCREMENT PRIMARY KEY, message CHAR(20)); INSERT INTO t1 (message) VALUES ("Testing"),("table"),("t1"); INSERT INTO t2 (message) VALUES ("Testing"),("table"),("t2"); CREATE TABLE total (a INT NOT NULL, message CHAR(20), KEY(a)) TYPE=MERGE UNION=(t1,t2);
Обратите внимание, что мы не создавали ключ UNIQUE
или
PRIMARY KEY
в таблице total
, поскольку ключ не
собирается быть уникальным в таблице total
.
Обратите внимание, что Вы можете также управлять файлом .MRG
вне сервера MySQL:
shell> cd /mysql-data-directory/current-database shell> ls -1 t1.MYI t2.MYI > total.MRG shell> mysqladmin flush-tables
Теперь Вы можете делать следующее:
mysql> select * from total; +---+---------+ | a | message | +---+---------+ | 1 | Testing | | 2 | table | | 3 | t1 | | 1 | Testing | | 2 | table | | 3 | t2 | +---+---------+
Чтобы повторно отобразить таблицу MERGE
, Вы можете делать
одно из следующего:
DROP
и пересоздайте ее.
ALTER TABLE table_name UNION(...)
.
.MRG
и выдайте FLUSH TABLE
на
таблице MERGE
и на всех основных таблицах, чтобы вынудить
драйвер прочитать новый файл определения.MyISAM
представляет собой заданный по умолчанию тип таблицы в
MySQL Version 3.23. Он основан на коде ISAM
и имеет
много полезных расширений.
Индекс сохранен в файле с расширением .MYI
(MYIndex), а
данные сохранены в файле с расширением .MYD
(MYData).
Вы можете проверять и ремонтировать таблицы MyISAM
командой
myisamchk
. Подробности в разделе
"4.4.6.7 Использование
myisamchk
для ремонта". Вы можете сжимать таблицы
MyISAM
с помощью команды myisampack
.
Следующее является новшествами в MyISAM
:
MyISAM
, который указывает, была
таблица закрыта правильно или нет. Если mysqld
запущен с опцией
--myisam-recover
, таблицы MyISAM
будут
автоматически проверены и восстановлены при открытии, если таблицы не были
закрыты правильно.
AUTO_INCREMENT
.
MyISAM
автоматически модифицирует его на операциях
INSERT/UPDATE
. Значение AUTO_INCREMENT
может быть
сброшено с помощью myisamchk
. Это делает столбцы
AUTO_INCREMENT
быстрее (по крайней мере на 10%), а старые числа
не будет многократно использоваться, как это было со старым
ISAM
. Обратите внимание, что когда AUTO_INCREMENT
определен на конце ключа из нескольких частей, работает старое поведение.
AUTO_INCREMENT
), дерево ключей будет
поделено так, чтобы высокий узел содержал только один ключ. Это улучшит
использование места в дереве ключей.
BLOB
и TEXT
теперь могут
быть корректно индексированы.
NULL
позволяются в индексированных столбцах. Это
занимает 0-1 байт на ключ.
myisamchk
может помечать таблицы как проверенные при запуске
с опцией --update-state
. myisamchk --fast
проверит
только те таблицы, которые не имеют этой метки.
myisamchk -a
сохраняет статистику для частей ключа (а не
только для целых ключей, как это было в ISAM
).
myisampack
может сжимать столбцы типов BLOB
и
VARCHAR
.
DATA/INDEX
DIRECTORY="path"
инструкции CREATE TABLE
).MyISAM
также поддерживает следующие вещи, которые MySQL будет
способен использовать в ближайшем будущем:
VARCHAR
: столбец
VARCHAR
начинается с длины, сохраненной в 2 байтах.
VARCHAR
теперь смогут иметь фиксированную или
динамическую длину записей.
VARCHAR
и CHAR
могут быть длиной до 64 КБ. Все
сегменты ключа имеют их собственное определение. Это даст возможность MySQL
иметь различные определения для столбцов.
UNIQUE
. Это
позволит Вам иметь UNIQUE
на любой комбинации столбцов в
таблице. (Но Вы не сможете искать на UNIQUE
индексе).Обратите внимание, что индексные файлы обычно намного меньше у
MyISAM
, чем у ISAM
. Это означает, что
MyISAM
обычно будет использовать меньшее количество ресурсов
системы, чем ISAM
, но будет нуждаться в большем времени CPU при
вставке данных в сжатый индекс.
Следующие параметры mysqld
могут использоваться, чтобы
изменить поведение таблиц MyISAM
. Подробности в разделе
"4.5.5.4 Синтаксис SHOW VARIABLES
".
Опция | Что она делает |
--myisam-recover=# | Автоматически восстанавливаются поврежденные таблицы. |
-O myisam_sort_buffer_size=# | Буфер, используемый при восстановлении таблиц. |
--delay-key-write-for-all-tables | Не сбрасывать буфер ключей на диск между записями для любой MyISAM таблицы. |
-O myisam_max_extra_sort_file_size=# | Используется, чтобы помочь MySQL решить, когда использовать медленный но безопасный метод создания индекса кэша ключей. ОБРАТИТЕ ВНИМАНИЕ , что этот параметр задан в мегабайтах! |
-O myisam_max_sort_file_size=# | Не использовать быстрый метод сортировки для созданного индекса, если временный файл больше, чем здесь указано. ОБРАТИТЕ ВНИМАНИЕ, что этот параметр задан в мегабайтах! |
Автоматическое восстановление активизировано, если Вы запускаете
mysqld
с опцией --myisam-recover=#
. Подробности в
разделе "4.1.1 Параметры командной
строки mysqld". При открытии таблица будет проверена, если она отмечена
как поврежденная, или если счетчик открытий для нее не равен 0, и Вы
работаете с опцией --skip-locking
. Если хоть одно из этих
условий выполнено, происходит следующее:
Если ремонт не смог восстановить все строки из предыдущей завершенной
инструкции, и Вы не определяли FORCE
как опцию для
myisam-recover
, автоматический ремонт прервется с сообщением
об ошибках в файле:
Error: Couldn't repair table: test.g00pages
Если Вы в этом случае использовали опцию FORCE
, Вы будете
взамен иметь предупреждение в файле ошибки:
Warning: Found 344 of 354 rows when repairing ./test/g00pages
Обратите внимание, что если Вы выполняете автоматический ремонт с опцией
BACKUP
, Вы должны иметь скрипт в cron, который автоматически
перемещает файлы с именами, подобными tablename-datetime.BAK, из
каталогов баз данных.
MySQL может поддерживать различные индексные типы, но нормальный тип ISAM
или MyISAM. Они используют индекс B-дерева, и Вы можете грубо вычислять
размер для индексного файла как (key_length+4)/0.67
. Это для
самого плохого случая, когда все ключи вставлены в сортируемом порядке, и мы
не имеем сжатых ключей.
Индексы строк сжимаются. Если первая индексная часть представляет собой
строку, она также будет префиксно сжата. Сжатие делает индексный файл меньше,
чем вышеупомянутые объекты, если столбец строки имеет много конечных пробелов
или столбец типа VARCHAR
, который не всегда используется для
данных полной длины. Префиксное сжатие используется на ключах, которые
начинаются со строки. Префиксное сжатие хорошо помогает, если имеется много
строк с идентичным префиксом.
В таблицах MyISAM
Вы можете также сжимать числа, определяя
PACK_KEYS=1
, когда Вы создаете таблицу. Это помогает, когда Вы
имеете много целочисленных ключей, которые имеют идентичный префикс, когда
числа сохранены в формате со старшим байтом в начале.
MyISAM поддерживает 3 различных типа таблиц. Два из них
будут выбраны автоматически в зависимости от типа столбцов, которые Вы
используете. Третий тип, сжатые таблицы, может быть создан только с помощью
внешнего инструмента myisampack
.
Это заданный по умолчанию формат. Он используется, когда таблица не
содержит столбцов типов VARCHAR
, BLOB
или
TEXT
.
Этот формат самый простой и наиболее безопасный. Он также самый быстрый из дисковых форматов. Быстродействие исходит из простого пути, которым данные могут быть найдены на диске. При поиске чего-либо с индексом и статическим форматом это очень просто. Только умножите номер строки на длину строки.
Также при просмотре таблицы очень просто читать постоянное число записей за каждую дисковую операцию чтения.
Кроме того, myisamchk
обычно может исправлять все записи за
исключением частично записанных. Обратите внимание, что в MySQL все индексы
могут всегда восстанавливаться.
CHAR
, NUMERIC
и DECIMAL
столбцы дополняются пробелами до ширины столбца.
myisamchk
, если огромное число
записей не удалено, и Вы хотите возвращать свободное дисковое пространство
операционной системе.
Этот формат используется, если таблица содержит столбцы типов
VARCHAR
, BLOB
или TEXT
, или если
таблица была создана с опцией ROW_FORMAT=dynamic
.
Этот формат немного сложнее потому, что каждая строка должна иметь заголовок, указывающий ее длину. Одна запись может также заканчиваться не в одном месте, когда она удлиннилась при обновлении.
Вы можете использовать OPTIMIZE table
или myisamchk
для дефрагментации таблицы. Если Вы имеете
статические данные, к которым часто обращаетесь или меняете их, неплохо бы
переместить эти динамические столбцы (например, VARCHAR
или
BLOB
) в другие таблицы, чтобы избежать фрагментации:
''
) для строковых столбцов или равными нулю для
числовых столбцов (это не столбцы, содержащие значения NULL
).
Если столбец строки имеет нулевую длину после удаления конечных пробелов, или
числовой столбец имеет нулевое значение, это отмечено в битовом массиве и не
сохранено на диск. Непустые строки сохранены как байт длины плюс строка.
myisamchk -r
, чтобы получить лучшую
эффективность. Используйте myisamchk -ei tbl_name
для сбора
некоторой статистики о таблице.
3+(number of columns+7)/8+(number of char columns)+ packed size of numeric columns+length of strings+ (number of NULL columns+7)/8Еще надо по 6 байт для каждой связи. Динамическая запись связана всякий раз, когда модификация вызывает расширение записи. Каждая новая связь будет по крайней мере 20 байт, так что следующее расширение, вероятно, войдет в ту же самую связь. Если нет, то будет создана другая связь. Вы можете проверять сколько там связей вызовом
myisamchk -ed
. Все связи могут быть
удалены с помощью команды myisamchk -r
.Этот тип таблиц предназначен только для чтения, он может быть сгенерирован
инструментом myisampack
(pack_isam
для таблиц типа
ISAM
):
myisampack
.
0
будут сохранены, используя 1 бит.
BIGINT
(8 байт) может быть сохранен как столбец
TINYINT
(1 байт), если все значения находятся в диапазоне от
0
до 255
.
ENUM
.
BLOB
или TEXT
.
myisamchk
.Формат файла, который использует MySQL, чтобы хранить данные, был многократно тщательно проверен, но всегда найдутся обстоятельства, которые могут разрушить таблицы базы данных.
Несмотря на то, что формат таблиц MyISAM очень надежен (все изменения для таблицы будут записаны перед возвратами инструкций SQL), Вы можете получать разрушенные таблицы, если случаются некоторые из следующих вещей:
mysqld
рухнул посреди записи.
Типичные признаки для разрушенной таблицы:
Incorrect key file for table: '...'. Try to
repair it
при выборе данных из таблицы.
Вы можете проверять, является ли таблица исправной, с помощью команды
CHECK TABLE
. Подробности в разделе
"4.4.4 Синтаксис CHECK TABLE
".
Вы можете отремонтировать разрушенную таблицу с помощью команды
REPAIR TABLE
. Подробности в разделе
"4.4.5 Синтаксис REPAIR TABLE
". Вы можете также отремонтировать таблицу, когда
mysqld
не запущен с помощью команды myisamchk
.
В этом случае наиболее важная вещь, знать из-за чего таблица была
повреждена. Проверить, не разрушался ли недавно mysqld
легко:
если в файле ошибок mysqld имеется недавняя строка перезапуска
restarted mysqld
, значит, разрушался и был перезапущен
автоматически. Если это не имеет место, значит, что-то не так с сервером.
Каждый MyISAM
-файл .MYI
имеет в заголовке
счетчик, который может использоваться, чтобы проверить, была ли таблица
закрыта правильно.
Если Вы получаете следующее предупреждение из CHECK TABLE
или
myisamchk
:
# clients is using or hasn't closed the table properly
Это означает, что этот счетчик вышел из синхронизации. Это пока еще не означает, что таблица разрушена, но Вы должны по крайней мере сделать проверку таблицы, чтобы удостовериться, что она в порядке.
Счетчик работает следующим образом:
FLUSH
или
потому, что не имеется участка памяти в кэше таблицы) счетчик уменьшается,
если таблица модифицировалась в любом месте.
Другими словами, единственные пути, которыми он может выйти из синхронизации такие:
MyISAM
-таблицы скопированы без LOCK
и
FLUSH TABLES
.
myisamchk --repair
или myisamchk
--update-state
на таблица, которая была в использовании у
mysqld
.
mysqld
используют таблицу, и каждый сделал
REPAIR
или CHECK
, в то время как таблица
использовалась другим сервером. В этой ситуации команда CHECK
безопасна (даже если Вы получите предупреждение с других серверов), но вот
REPAIR
нужно избегать, поскольку это в настоящее время заменяет
файл данных на новый, который не будет передан на другие серверы.Всего: 450 страниц в формате А4.
MySQL имеет продвинутую, но ненормативную систему защиты и привилегий. Этот подробно раздел описывает, как она работает.
Любой, использующий MySQL на компьютере, связанном с Internet, должен прочитать этот раздел, чтобы избежать наиболее общих ошибок защиты.
Очень важно уделить внимание проблемам безопасности всего сервера (а не только MySQL) и защите от всех типов атак.
MySQL использует защиту, основанную на списках управления доступом (Access Control Lists ACL) для всех подключений, запросов и других операций, которые пользователь может пытаться выполнять. Имеется также поддержка для соединений, зашифрованных SSL между клиентами и сервером MySQL. Многие из понятий, обсуждаемых здесь, не специфические для MySQL: те же самые общие идеи применимы вообще почти ко всем прикладным программам.
При запуске MySQL следуйте этим руководящим принципам:
user
В БАЗЕ ДАННЫХ mysql
!
GRANT
и
REVOKE
используются для управления доступом к MySQL. Не
предоставляйте большие привилегии, чем необходимо. Никогда не предоставляйте
привилегии всем хостам.
Контрольный список:
mysql -u root
. Если Вы способны соединиться
успешно с сервером без запроса о пароле, Вы имеете проблемы. Любой может
соединяться с Вашим сервером MySQL как MySQL пользователь root
с полными привилегиями! Поставьте пароль пользователя.
SHOW GRANTS
и проверьте, кто имеет
доступ к какой базе данных. Удалите те привилегии, которые не являются
необходимыми, с помощью команды REVOKE
.MD5()
или другую одностороннюю хеш-функцию.
nmap
. MySQL по умолчанию использует порт 3306. Этот порт
должен быть недоступен кому попало. Другой простой способ проверить, является
или нет Ваш порт MySQL открытым, состоит в том, чтобы попробовать следующую
команду с некоторой удаленной машины, где server_host
задает
имя хоста Вашего сервера MySQL:
shell> telnet server_host 3306Если Вы получаете подключение и некоторые символы, порт открыт, и должен быть закрыт на Вашем firewall или маршрутизаторе, если Вы не имеете причин хранить его открытым. Если
telnet
только висит или от подключения
отказываются, все ХОРОШО; порт блокирован.; DROP DATABASE mysql;
''.
Также не забудьте проверять числовые данные. Иногда помогает заключить все
числовые значения в апострофы. Например: SELECT * FROM table WHERE
ID='234'
вместо SELECT * FROM table WHERE ID=234
.
MySQL автоматически преобразует эту строку в число и удаляет нечисловые
символы из нее. Контрольный список:
%22
(`"'), %23
(`#') и %27
(`'').
addslashes()
. Начиная с PHP 4.0.3,
появилась функция mysql_escape_string()
, которая основана на
одноименной функции в MySQL C API.mysql_escape_string()
.escape
и quote
для потоков запроса.quote()
.PreparedStatement
.tcpdump
и
strings
. Для большинства случаев Вы можете проверять, шифрованы
или нет потоки данных MySQL, выдавая команду:
shell> tcpdump -l -i eth0 -w - src or dst port 3306|stringsЭто работает под Linux и должно работать с маленькими модификациями под другими системами. Если Вы не видите данные, это не всегда означает, что они фактически зашифрованы. Если Вы нуждаетесь в хорошей защите, Вы должны проконсультироваться с экспертом защиты.
Когда Вы соединяетесь с сервером MySQL, Вы обычно должны использовать пароль. Он не передается открытым текстом, однако, алгоритм шифрования не очень силен, и с некоторым усилием умный нападаюший может расколоть пароль, если может перехватить трафик. Если подключение между пользователем и сервером проходит недоверенную сеть, Вы должны использовать SSH-туннель, чтобы шифровать связь. Увы, хакеры сделали шифрование совершенно мирной связи обычным делом. А думали ли мы все, что через три года будем совершенно спокойно воспринимать шифрование данных не в военных системах, а дома?
Вся другая информация будет перемещена как текст, который может читаться
любым, кто способен наблюдать подключение. Если Вы обеспокоены относительно
этого, Вы можете использовать сжатый протокол (в MySQL версии 3.22 и выше),
чтобы делать такое чтение намного тяжелее. Чтобы сделать связь более
безопасной, Вы должны использовать ssh
. Вы можете скачать
исходные тексты клиентской части ssh
с
http://www.openssh.org, коммерческая
версия клиента ssh
доступна на
http://www.ssh.com. Теперь Вы можете
получить шифрованное TCP/IP подключение к серверу MySQL.
Чтобы сделать систему MySQL безопасной, Вы должны внимательно рассмотреть следующие предложения:
mysql -u other_user db_name
, если этот самый
other_user
не имеет никакого пароля. Это общее поведение при
работе с прикладными программами клиент/сервер, где клиент может определять
любое имя пользователя. Вы можете изменять пароль всех пользователей,
редактируя скрипт mysql_install_db
прежде, чем Вы его выполните,
или только пароль для MySQL-пользователя root
:
shell> mysql -u root mysql mysql> UPDATE user SET Password=PASSWORD('new_password') WHERE user='root'; mysql> FLUSH PRIVILEGES;
root
.
Это очень опасно, потому что любой пользователь с привилегиями
FILE
будет способен создать файлы как root
(например, ~root/.bashrc
). Чтобы предотвращать это,
mysqld
откажется выполняться как root
, если это не
определено, непосредственно используя опцию --user=root
.
mysqld
может быть выполнен как обычный непривилегированный
пользователь. Вы можете также создать нового Unix-пользователя
mysql
, чтобы сделать все даже более безопасным. Если Вы
выполняете mysqld
как другой Unix-пользователь, Вы не должны
изменять имя пользователя root
в таблице user
потому, что имена MySQL-пользователей не имеют никакого отношения к именам
пользователей Unix. Чтобы запустить mysqld
как другой
пользователь Unix, добавьте строку user
, которая определяет имя
пользователя к группе [mysqld]
в файле /etc/my.cnf
или в файле my.cnf в каталоге данных сервера. Например:
[mysqld] user=mysqlЭто заставит сервер запускаться как обозначенный пользователь, неважно запускаете ли Вы его вручную, используя
safe_mysqld
или
mysql.server
. Подробности в разделе
"8.3.2 Как выполнить MySQL
как нормальный пользователь"..
--skip-symlink
). Это особенно важно, если Вы выполняете
mysqld
как root, так как любой пользователь, который имеет
доступ для записи к каталогам данных, может удалить любой файл в системе!
Подробности в разделе "5.6.1.2
Использование символических ссылок на таблицы".
mysqld
является единственным, кому позволено чтение-запись в
каталогах баз данных.
mysqladmin processlist
показывает текст в настоящее время
выполняющихся запросов, так что любой пользователь, которому дозволено эту
команду выдавать, мигом увидит, что кто-то выдает запрос типа
UPDATE user SET password=PASSWORD('not_secure')
...
mysqld
резервирует подключение для пользователей, которые имеют
привилегию process, чтобы MySQL-пользователь
root
мог войти и работать, даже если все нормальные подключения
уже находятся в использовании.
mysqld
daemon! Чтобы сделать это
немного более безопасным, все файлы, сгенерированные
SELECT ... INTO OUTFILE
читаются кем угодно, и Вы не можете
записывать поверх существующих файлов.
Привилегия file может также использоваться, чтобы читать
любой файл, доступный для Unix-пользователя, от имени которого выполняется
сервер. Это может быть злоупотреблено, например, используя LOAD
DATA
, чтобы загрузить /etc/passwd в таблицу, которая может
затем читаться с помощью SELECT
.
max_user_connections
в mysqld
.mysqld
, связанные с защитойСледующие параметры mysqld
воздействуют на защиту:
--safe-show-database
SHOW DATABASES
возвращает только те базы
данных, для которых пользователь имеет некоторую привилегию.
--safe-user-create
GRANT
, если он не имеет права INSERT
на
таблице mysql.user
. Если Вы хотите давать пользователю доступ к
созданию новых пользователей с теми привилегиями, которые он имеет право
предоставить, Вы должны дать ему следующую привилегию:
GRANT INSERT(user) on mysql.user to 'user''hostname';Это гарантирует, что пользователь не может изменять любые столбцы привилегий непосредственно, а должен использовать команду
GRANT
, чтобы дать
привилегии другим пользователям.
--skip-grant-tables
mysqladmin flush-privileges
или mysqladmin reload
.
--skip-name-resolve
Host
в
таблицах предоставления привилегий должны быть IP-адресами или
localhost
.
--skip-networking
mysqld
должно быть выполнено через сокеты Unix. Эта опция очень
рекомендуется на системах, где позволяются только локальные запросы. Эта
опция не подходит для систем, которые используют MIT-PTHREADS потому, что
пакет MIT-PTHREADS не поддерживает Unix-сокеты.
--skip-show-database
SHOW DATABASES
не будет возвращать ничего.Первичная функция системы привилегий MySQL состоит в том, что она должна опознать пользователя, соединяющегося с данного компьютера, и сопоставить этого пользователя с привилегиями на базе данных типа select, insert, update и delete.
Дополнительные функциональные возможности включают способность иметь
анонимного пользователя и предоставлять привилегии для MySQL-функций, типа
LOAD DATA INFILE
, и административных операций.
Система привилегий MySQL гарантирует, что все пользователи могут делать точно те дела, которые им будут позволены. Когда Вы соединяетесь с сервером MySQL, Вы будете идентифицированы не только по логину, который ввели, но и по адресу хоста, с которого зашли в сеть.
MySQL позволяет Вам отличить пользователей с различных компьютеров, которые, случается, имеют то же самое имя, Вы можете предоставлять один набор привилегий для подключений с одной системы, и совсем другой для того же имени, но с другой машины.
Управление доступом MySQL включает две стадии:
Сервер использует таблицы 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'
соответственно
использовалась бы для подтверждения подключений, сделанных на сервер
пользователем bob
с компьютера thomas.loc.gov
.
Точно так же запись таблицы 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 или позже.
Поля привилегий указывают привилегии, предоставленные записью таблицы, то есть какие операции могут выполняться. Сервер объединяет информацию из различных таблиц предоставления привилегий, чтобы сформировать полное описание прав данного пользователя. Правила, используемые, чтобы это сделать, подробно описаны в разделе "4.2.9 Контроль доступа, стадия 2: Проверка запросов".
Поля контекста представляют собой строки, объявленные как показано ниже. Значение по умолчанию для каждой: пустая строка:
Имя поля | Тип | |
Host | CHAR(60) | |
User | CHAR(16) | |
Password | CHAR(16) | |
Db | CHAR(64) |
(CHAR(60) для таблиц tables_priv и
columns_priv ) |
Table_name | CHAR(60) | |
Column_name | CHAR(60) |
В таблицах user
, db
и host
все поля
привилегий объявлены как ENUM('N','Y')
: каждое может иметь
значение 'N'
или 'Y'
, значение по умолчанию
'N'
.
В таблицах tables_priv
и 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
, чтобы обратиться к нескольким компьютерам. Например, если Вы
хотите, чтобы пользователь мог работать с базой данных с нескольких
компьютеров в Вашей сети, оставьте значение Host
пустым в записи
пользователя таблицы db
, затем заполните таблицу
host
, создав в ней запись для каждого из компьютеров. Этот
механизм описан более подробно в разделе
"4.2.9
Контроль доступа, стадия 2: Проверка запросов".tables_priv
и columns_priv
подобны
таблице db
, но более точны: они применяются в уровнях столбца и
таблицы, а не на уровне всей базы данных.Обратите внимание, что административные привилегии
(reload, shutdown и т.д.) определены только
в таблице user
. Это потому, что административные операции
выполняются непосредственно на сервере и не специфические для базы данных,
так что нет никакой причины внести в список такие привилегии в других
таблицах. Фактически, только таблица user
должна использоваться,
чтобы определить, можете ли Вы выполнять административную операцию или нет.
Привилегия file также определена только в таблице
user
. Это не административная привилегия, но Ваша способность
читать или писать файлы на компьютере сервера также независима от базы
данных, к которой Вы обращаетесь.
Сервер mysqld
читает содержание таблиц только один раз, при
своем запуске. Изменения для таблиц предоставления привилегий вступают в
силу как сказано в разделе "4.3.3
Когда изменения привилегий вступают в силу".
Когда Вы изменяете содержание таблиц предоставления, стоит удостовериться,
что Ваши изменения установили привилегии так, как Вы хотите. Для справки в
диагностировании проблем обратитесь в раздел
"4.2.10 Причины ошибки Access
denied
. Проблемы с защитой подробно рассмотрены в разделе
"4.2.2 Как защитить MySQL от хакеров".
Полезный диагностический инструмент: скрипт mysqlaccess
,
который Yves Carlier предоставил для дистрибутива MySQL. Вызовите
mysqlaccess
с опцией --help
, чтобы выяснить, как
это работает. Обратите внимание, что mysqlaccess
проверяет
доступ, используя только таблицы user
, db
и
host
. Это не проверяет привилегии уровня столбца или таблицы.
Информация относительно привилегий пользователя сохранена в таблицах
user
, db
, host
,
tables_priv
и columns_priv
в базе данных
mysql
. Сервер MySQL читает содержание этих таблиц при запуске
и при обстоятельствах, перечисленных в разделе
"4.3.3 Когда изменения
привилегий вступают в силу".
Имена, используемые в этом руководстве, чтобы обратиться к привилегиям, обеспеченным MySQL, показываются ниже, наряду с именем столбца таблицы, связанным с каждой привилегией в таблицах предоставления привилегий и контекста, в котором данная привилегия применяется:
Привилегия | Столбец | Контекст (поле) действия |
select | Select_priv | таблицы |
insert | Insert_priv | таблицы |
update | Update_priv | таблицы |
delete | Delete_priv | таблицы |
index | Index_priv | таблицы |
alter | Alter_priv | таблицы |
create | Create_priv | базы данных, таблицы или индексы |
drop | Drop_priv | базы данных или таблицы |
grant | Grant_priv | базы данных или таблицы |
references | References_priv |
базы данных или таблицы |
reload | Reload_priv | серверное администрирование |
shutdown | Shutdown_priv | серверное администрирование |
process | Process_priv | серверное администрирование |
file | File_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 и
flush-tables |
shutdown | shutdown |
process | processlist ,
kill |
Команда reload
сообщает, что сервер должен заново прочитать
таблицы предоставления привилегий. Команда refresh
сбрасывает на
диск все таблицы, закрывает и заново открывает журналы. Привилегия
flush-privileges
является синонимом для reload
.
Другие команды flush-*
выполняют функции, подобные
refresh
, но в более ограниченном контексте, и могут быть
предпочтительны в некоторых ситуациях. Например, если Вы хотите только
сбросить на диск журналы, команда flush-logs
представляет собой
лучший выбор, чем refresh
.
Команда shutdown
выключает сервер.
Команда processlist
отображает информацию относительно
процессов, выполняющихся внутри сервера. Команда kill
уничтожает
потоки сервера. Вы всегда можете отображать или уничтожать Ваши собственные
процессы, но Вы нуждаетесь в привилегии process, чтобы
отображать или уничтожать процессы, инициализированные другими
пользователями. Подробности в разделе
"4.5.4 Синтаксис KILL
".
Некоторые предосторожности при предоставлении привилегий:
SELECT
.
Это включает содержание всех баз данных на сервере!
mysql
могут использоваться, чтобы
изменить пароли и другую информацию привилегий доступа. Пароли сохранены
зашифрованными, так что злонамеренный пользователь не сможет просто читать
их, чтобы узнать простой текстовый пароль. Если пользователь может обращаться
к столбцу пароля в mysql.user
, он может использовать это, чтобы
зарегистрировать нового пользователя на сервере MySQL.Имеются некоторые вещи, которые Вы не можете делать с системой привилегий MySQL:
Клиент 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
. Подробности в разделе
"4.1.2 Файл опций my.cnf".
mysql
использует значения по умолчанию для параметров
подключения, которые отсутствуют в командной строке:
localhost
.
-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Подробности в разделе "4.1.2 Файл опций my.cnf".
mysql
в переменной MYSQL_HOST
. Имя пользователя MySQL может быть
определено, используя USER
(это только для Windows). Пароль
может быть определен, используя MYSQL_PWD
(но это опасно; см.
следующий раздел). Подробности в разделе
"Приложение 2. Переменные окружения
".Когда Вы пытаетесь соединиться с сервером MySQL, он принимает или отклоняет подключение, исходя из Вашей идентификации и того, можете ли Вы подтвердить ее паролем. Если нет, сервер отвергает доступ полностью. Иначе сервер принимает подключение, затем вводит Стадию 2 и ждет запросы.
Идентификация основана на двух частях информации:
Проверка выполняется, используя три поля области (контекста) таблицы
user
(Host
, User
и
Password
). Сервер принимает подключение только, если запись
таблицы user
соответствует Вашему hostname и имени пользователя,
и Вы вводите правильный пароль.
Значения в полях области (контекста) таблицы user
могут быть
определены следующим образом:
Host
может быть hostname, IP-адресом или
localhost
, чтобы указать локальный компьютер.
Host
.
'%'
поля Host
соответствует любому
имени хоста (hostname).
Host
означает, что привилегия должна быть
получена методом операции логического AND с записью в таблице
host
, которая соответствует данному имени. Вы можете найти
большее количество информации относительно этого в следующей главе.
Host
, определенных как IP, Вы можете определять netmask,
указывая, сколько бит адреса использовать для сетевого адреса. Например:
GRANT ALL PRIVILEGES on db.* to david@'192.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
отвергает соответствие имен хостов, которые начинаются с цифр и точки. Таким
образом, если Вы имеете компьютер с именем наподобие
3.6.foo.com
, его имя никогда не будет соответствовать столбцу
Host
таблиц. Только IP-адрес может соответствовать символам
подстановки в IP-адресе.
Входящее подключение может быть согласовано более, чем с одной записью в
таблице user
. Например, подключение пользователя
fred
с машины thomas.loc.gov
согласовано
несколькими записями, показанными выше. Как сервер выбирает, которую запись
использовать в данной ситуации? Он решает этот вопрос, сортируя таблицу
user
после ее чтения при запуске. Затем записи просматриваются в
отсортированном порядке. Используется первое совпадение.
Сортировка таблицы user
работает следующим образом.
Предположим, что таблица user
выглядит следующим образом:
+-----------+----------+- | Host | User | ... +-----------+----------+- | % | root | ... | % | jeffrey | ... | localhost | root | ... | localhost | | ... +-----------+----------+-
Когда сервер читает таблицу, он располагает записи с наиболее
специфическими значениями Host
вначале ('%'
в
столбце Host
означает любой компьютер, а, стало быть, наименее
специфический). Записи с одинаковыми значениями Host
упорядочиваются с наиболее специфическими значениями User
(пустое значение User
означает любого пользователя, и наименее
специфическое). Возникающая в результате сортировки таблица user
выглядит следующим образом:
+-----------+----------+- | Host | User | ... +-----------+----------+- | localhost | root | ... | localhost | | ... | % | jeffrey | ... | % | root | ... +-----------+----------+-
Когда
предпринято подключение, сервер просматривает отсортированные записи и
использует первое найденное соответствие. Для подключения пользователя
jeffrey
с машины localhost
записи со значением
'localhost'
в столбце Host
окажутся первыми. Из них
подходит запись с пустым именем пользователя. Запись
'%'/'jeffrey'
тоже подходит, но она не первая.
Имеется другой пример. Предположите, что таблица user
выглядит следующим образом:
+----------------+----------+- | Host | User | ... +----------------+----------+- | % | jeffrey | ... | thomas.loc.gov | | ... +----------------+----------+-
Отсортированная таблица будет выглядеть так:
+----------------+----------+- | Host | User | ... +----------------+----------+- | thomas.loc.gov | | ... | % | jeffrey | ... +----------------+----------+-
Подключение пользователя jeffrey
с машины
thomas.loc.gov
согласовано первой записью в то время, как
подключение jeffrey
с машины whitehouse.gov
соответствует второй записи.
Общее неправильное мнение состоит в том, что первыми будут использованы записи, в которых имя пользователя указано явно. Это не так! Только что было показано, что запись, использованная первой, имени пользователя в явном виде не имела вовсе.
Если Вы имеете проблемы при соединении с сервером, распечатайте таблицу
user
и отсортируйте ее вручную, чтобы видеть, где первое
соответствие будет сделано.
Как только Вы устанавливаете подключение, сервер вводит Стадию 2. Для
каждого запроса, который входит на подключении, сервер проверяет, имеете ли
Вы достаточные привилегии, чтобы выполнить его, основываясь на типе операции.
Эти привилегии могут исходить из любой из таблиц: user
,
db
, host
, tables_priv
или
columns_priv
. Таблицы предоставления привилегий управляются с
помощью команд GRANT
и REVOKE
. Подробности в
разделе "4.3.1 Синтаксис GRANT
и
REVOKE
".
Таблица user
предоставляет привилегии, которые назначены Вам
на глобальном основании, и это применяется независимо от того, какова текущая
база данных. Например, если таблица user
предоставляет Вам
привилегию delete, Вы можете удалять строки из любой базы
данных на сервере! Другими словами, привилегии таблицы user
являются глобальными. Мудро предоставить привилегии в таблице
user
только суперпользователям типа администраторов базы данных
или сервера в целом. Для других пользователей Вы должны оставить привилегии в
таблице user
в значении 'N'
и давать их только при
использовании таблиц db
и host
.
Таблицы db
и host
предоставляют специфические
для базы данных привилегии. Значения в полях области могут
быть определены так:
Host
и Db
любой таблицы.
'%'
в поле Host
таблицы
db
означает любой компьютер. Пустое значение Host
в таблице db
предписывает брать информацию из таблицы
host
.
'%'
или пустое значение Host
в таблице
host
означает любой компьютер.
'%'
или пустое значение Db
в любой таблице
означает любую базу данных.
User
в любой таблице
соответствует анонимному пользователю.Таблицы db
и host
читаются и сортируются при
запуске сервера по тем же правилам, что и таблица user
.
Таблицы tables_priv
и columns_priv
предоставляют
специфические для таблицы и столбца привилегии. Значения в полях области
(контекста) могут быть определены так:
Host
любой таблицы.
'%'
или пустое значение Host
в любой таблице
означает любой компьютер.
Db
, Table_name
и Column_name
не могут содержать групповые символы или быть пустыми в любой таблице.Таблицы tables_priv
и columns_priv
сортируются
по полям Host
, Db
и User
. Это подобно
сортировке таблицы db
, хотя сортировка более простая потому, что
только поле Host
может содержать групповые символы.
Процесс проверки запроса описан ниже.
Для административных запросов (shutdown,
reload и т.д.), сервер проверяет только запись таблицы
user
потому, что это единственная таблица, которая определяет
административные привилегии. Доступ предоставляется, если запись позволяет
запрошенную операцию. Например, если Вы хотите выполнить mysqladmin
shutdown
, но Ваша запись в таблице user
не предоставляет
Вам привилегию shutdown, доступ будет отклонен без всякой
проверки таблиц db
или host
.
Для связанных с базой данных запросов (insert,
update и т.д.), сервер сначала проверит глобальные
привилегии (суперпользователя) по записям в таблице user
. Если
запись позволяет запрошенную операцию, доступ предоставляется. Если
глобальные привилегии в таблице user
недостаточны, сервер
определяет специфические для базы данных привилегии пользователя, проверяя
таблицы db
и host
:
db
соответствия полей
Host
, Db
и User
. Поля
Host
и User
должны соответствовать hostname
соединяющегося клиентского компьютера и MySQL-имени пользователя. Поле
Db
должно соответствовать базе данных, к которой пользователь
хочет обращаться. Если не имеется никакой записи для Host
и
User
, доступ будет отклонен.
db
и ее поле
Host
не пустое, то данная запись определяет специфические для
базы данных привилегии пользователя.
db
поле
Host
является пустым, это выражает, что таблица
host
перечисляет, какие именно компьютеры имеют доступ к базе
данных. В этом случае дальнейшая поисковая работа ведется в таблице
host
, чтобы найти соответствие полей Host
и
Db
. Если соответствий в таблице host
нет, доступ
будет отклонен. Если имеется соответствие, специфические для базы данных
привилегии пользователя будут вычислены как пересечение (но не
объединение!) привилегий в таблицах db
и host
,
то есть, привилегий, которые являются 'Y'
, в обеих записях.После определения специфических для базы данных привилегий,
предоставленных записями таблиц 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
),
чтобы удостовериться, что Ваши привилегии доступа фактически установлены так,
как Вы ожидаете.
Access denied
Если Вы сталкиваетесь с ошибкой Access denied
, когда пробуете
соединиться с сервером MySQL, посмотрите список ниже. Там приведены наиболее
часто встречающиеся проблемы.
mysql_install_db
, чтобы установить начальное содержание таблицы
предоставления привилегий? Если нет, выполните. Подробности в разделе
"4.3.4 Установка начальных
привилегий MySQL". Проверьте начальные привилегии, выполнив эту команду:
shell> mysql -u root testСервер должен позволить Вам соединиться без ошибки. Вы должны также удостовериться, что Вы имеете файл user.MYD в каталоге баз данных MySQL. Обычно это $PATH/var/mysql/user.MYD, где
$PATH
имя пути к корню установки MySQL.
shell> mysql -u root mysqlСервер должен позволить Вам соединиться, потому что MySQL-пользователь
root
первоначально не имеет никакого пароля. Это дыра в защите,
так что поставьте пароль как можно быстрее! Если Вы пробуете соединиться как
root
и получаете эту ошибку:
Access denied for user: '@unknown' to database mysqlЭто означает, что Вы не имеете записи в таблице
user
со
значением 'root'
столбца User
, и что
mysqld
не может получить IP-адрес для Вашего клиента. В этом
случае Вы должны перезапустить сервер с опцией
--skip-grant-tables
и отредактировать Ваш файл
/etc/hosts или \windows\hosts, чтобы добавить в него запись
для Вашего компьютера.
shell> mysqladmin -u root -pxxxx ver Access denied for user: 'root@localhost' (Using password: YES)Это означает, что Вы используете неправильный пароль. Подробности в разделе "4.3.6 Установка паролей". Если Вы забыли пароль root, то можете перезапустить
mysqld
с
опцией --skip-grant-tables
, чтобы изменить пароль.
Если Вы получаете вышеупомянутую ошибку, даже если Вы не определили пароль,
это означает, что есть неправильный пароль в файле my.ini
.
Подробности в разделе "4.1.2 Файлы опций
my.cnf". Вы можете отказаться от использования файлов опций с помощью
параметра командной строки --no-defaults
:
shell> mysqladmin --no-defaults -u root ver
mysql_fix_privilege_tables
? Если нет, сделайте это.
Структура таблиц поменялась после версии 3.22.11, когда инструкция
GRANT
стала функциональной.
PASSWORD()
, если Вы устанавливаете
пароль инструкцией INSERT
, UPDATE
или SET
PASSWORD
. Функция PASSWORD()
не нужна, если Вы
определяете пароль, используя инструкцию GRANT ... INDENTIFIED
BY
или вызов команды mysqladmin password
. Подробности в
разделе "4.3.6 Установка паролей".
localhost
представляет собой синоним для Вашего локального
hostname, а также заданный по умолчанию компьютер, с которым клиент пробует
соединяться, если Вы не определяете никакого компьютер явно. Однако,
подключения с localhost
не работают, если Вы работаете на
системе, которая использует MIT-pthreads (подключения localhost
сделаны, используя Unix-сокеты, которые не поддержаны MIT-pthreads). Чтобы
избежать этой проблемы на таких системах, Вы должны использовать опцию
--host
, чтобы назвать компьютер сервера явно. Это будет делать
TCP/IP-подключение (не через сокеты!) к серверу mysqld
. В этом
случае Вы должны иметь Ваш реальный hostname в записях таблицы
user
на компьютере сервера (даже если Вы запускаете клиент и
сервер на одной физической машине).
Access denied
при попытке
соединиться с базой данных с помощью вызова
mysql -u user_name db_name
, Вы можете иметь проблему с таблицей
user
. Проверьте это, выполняя mysql -u root mysql
и
выдавая эту инструкцию SQL:
mysql> SELECT * FROM user;Результат должен включать запись со столбцами
Host
и
User
, соответствующими hostname Вашего компьютера и Вашему
MySQL-имени пользователя.
user
, которая
точно соответствует hostname и имени пользователя, которые были даны в
сообщении об ошибках. Например, если Вы получаете сообщение об ошибках,
которое содержит строку Using password: NO
, это означает, что Вы
пробовали войти в систему без пароля.
user
, которая соответствует этому компьютеру:
Host ... is not allowed to connect to this MySQL serverВы можете исправить это, используя инструмент командной строки
mysql
(на серверной системе!), чтобы добавить строку в таблицу
user
, db
или host
для комбинации
user/hostname, из которой Вы пробуете соединяться, и затем выполнить
mysqladmin flush-privileges
. Если Вы не используете
MySQL Version 3.22, и Вы не знаете IP-адрес или hostname машины, с которой Вы
соединяетесь, Вы должны поместить '%'
в столбец
Host
таблицы user
и перезапустить
mysqld
с опцией --log
на серверной машине. После
попытки соединяться с машины пользователя, информация в файле регистрации
MySQL укажет, как Вы в действительности соединялись. Теперь следует заменить
'%'
в таблице user
фактическим hostname, который
обнаруживается в файле регистрации. Иначе Вы будете иметь систему,
которая является опасной.
Другая причина для этой ошибки под Linux в том, что Вы используете двоичную
версию MySQL, которая компилируется не с той версией glibc, которую Вы
используете. В этом случае Вы должны или обновить OS/glibc, или скачать
исходник MySQL и откомпилировать их непосредственно. RPM-пакет с исходниками
обычно тривиален в компиляции и установке, так что это не большая проблема.
shell> mysqladmin -u root -pxxxx -h some-hostname ver Access denied for user: 'root' (Using password: YES)Это означает, что MySQL получил некоторую ошибку при попытке преобразования между IP и hostname. В этом случае Вы можете выполнять
mysqladmin
flush-hosts
, чтобы сбросить внутренний кэш DNS. Подробности в разделе
"5.5.5 Как MySQL использует DNS". Некоторые
постоянные решения, которые могут помочь:
mysqld
с опцией --skip-name-resolve
.
mysqld
с опцией --skip-host-cache
.
localhost
.
/etc/hosts
.mysql -u root test
работает, но
mysql -h your_hostname -u root test
возвращает ошибку
Access denied
, то Вы не можете иметь правильное имя для Вашего
компьютера в таблице user
. Общая проблема здесь состоит в том,
что значение Host
в записи таблицы определяет
неквалифицированный hostname, но подпрограммы конвертации имен в адреса Вашей
системы возвращают полностью квалифицированное имя домена (или наоборот).
Например, если Вы имеете запись с компьютером 'tcx'
в таблице
user
, но Ваш DNS сообщает MySQL, что Ваш hostname является
tcx.subnet.se
, запись не будет работать. Попробуйте добавить
запись к таблице user
, которая содержит IP-адрес Вашего
компьютера как значение столбца Host
. Альтернативно, Вы могли бы
добавлять к таблице user
запись со значением Host
,
которое содержит групповой символ, например, tcx.%
. Однако,
использование имен, кончающихся на `%', опасно и
строго не рекомендуется!
mysql -u user_name test
корректно работает, а вот
mysql -u user_name other_db_name
работать и не думает, Вы не
имеете записи для other_db_name
, перечисленной в таблице
db
.
mysql -u user_name db_name
корректно работает, когда
выполнена на машине сервера, но
mysql -u host_name -u user_name db_name
не работает, когда
выполнена на другой машине, Вы имеете машину пользователя, не перечисленную в
таблицах user
или db
.
Access
denied
, удалите из таблицы user
все записи, которые имеют
значения Host
, содержащие групповые символы (записи, которые
содержат `%' или `_'). Очень частая ошибка состоит
в том, чтобы вставить новую запись с Host
='%'
и
User
='some user'
, думая, что это позволит Вам
определять localhost
, чтобы соединиться из той же самой машины.
Причина того, что это не работает в том, что заданные по умолчанию привилегии
включают запись с Host
='localhost'
и
User
=''
. Поскольку эта запись имеет в поле
Host
значение 'localhost'
, которое является более
специфическим, чем '%'
, именно она используется в предпочтении
при соединении из localhost
! Правильная процедура должна вставить
вторую запись с Host
='localhost'
и
User
='some_user'
или удалить запись, где
Host
='localhost'
и
User
=''
.
db
или host
:
Access to database deniedЕсли запись из таблицы
db
имеет пустое значение в столбце
Host
удостоверьтесь, что имеется одна или большее количество
соответствующих записей в таблице host
, определяющих, к которым
компьютерам применяется запись таблицы db
.
Если Вы получаете ошибку при использование команд SQL SELECT ... INTO
OUTFILE
или LOAD DATA INFILE
, Ваша запись в таблице
user
, вероятно, не имеет привилегию file.
Access denied
, когда Вы выполняете клиента
без параметров вообще, удостоверьтесь, что Вы не определили старый пароль в
любом из файлов опций!
INSERT
или
UPDATE
), и Ваши изменения игнорируются, не забывайте, что Вы
должны выдать инструкцию FLUSH PRIVILEGES
или выполнить команду
mysqladmin flush-privileges
, чтобы заставить сервер заново
прочитать таблицы привилегий. Иначе Ваши изменения не будут иметь никакого
эффекта до очередного перезапуска сервера. Не забудьте, что после того, как
Вы устанавливаете пароль root
командой UPDATE
,
Вы не должны определять его до того, как сбросите привилегии на диск потому,
что сервер не будет знать о смене пароля!
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
с опцией
отладки (например, --debug=d,general,query
). Это будет печатать
хост и информацию пользователя относительно предпринятых подключений, а также
информацию относительно каждой выданной команды. Подробности в разделе
"6.1.2 Создание файлов трассировки
".
mysqldump mysql
.
Как всегда регистрируйте Вашу проблему при помощи скрипта
mysqlbug
. Подробности в разделе
"1.4.1 Как сообщать об ошибках и проблемах
". В некоторых случаях придется перезапустить mysqld
с
опцией --skip-grant-tables
, чтобы выполнить
mysqldump
.Поскольку таблицы MySQL сохранены как файлы, просто делайте копию. Чтобы
получать непротиворечивую копию, скомандуйте LOCK TABLES
на
релевантных таблицах и дополните это командой FLUSH TABLES
для
них, дабы все данные были гарантированно сброшены на диск. Вам нужна только
блокировка записи. Это позволяет другим потокам продолжать делать запросы к
таблицам в то время, как Вы делаете копию файлов в каталоге баз данных.
Команда FLUSH TABLE
необходима, чтобы гарантировать, что все
активные индексные страницы записаны на диск прежде, чем Вы
запускаете процесс копирования.
Если Вы хотите делать копию уровня SQL из таблицы, Вы можете использовать
SELECT INTO OUTFILE
или BACKUP TABLE
. Подробности в
разделе "4.4.2 Синтаксис BACKUP
TABLE
".
Другой способ поддержать базу данных состоит в том, чтобы использовать
программу mysqldump
или скрипт mysqlhotcopy
.
Подробности в разделах
"4.8.5 mysqldump, Дамп структур таблиц и
данных" и "4.8.6 mysqlhotcopy,
Копирование баз данных и таблиц MySQL".
shell> mysqldump --tab=/path/to/some/dir --opt --fullили
shell> mysqlhotcopy database /path/to/some/dirВы можете также просто копировать все файлы таблицы (*.frm, *.MYD и *.MYI), пока сервер что-нибудь не модифицирует. Скрипт
mysqlhotcopy
использует этот метод.
mysqld
запущен, остановите его, а
затем запустите с опцией --log-update[=file_name]
. Подробнее об
этой опции можно узнать в разделе "4.9.3
Файл регистрации модификаций". Файлы протоколов предоставляют Вам
информацию относительно того, что изменилось со времени
последнего вызова mysqldump
.Если Вы должны восстановить что-либо, попробуйте восстанавливать Ваши
таблицы, используя REPAIR TABLE
или myisamchk -r
.
Это эффективно в 99.9% случаев. Если myisamchk
ничего хорошего
не сделал, попробуйте следующую процедуру (это будет работать только, если Вы
запустили MySQL с опцией --log-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 ...
. Чтобы избежать двойных записей, Вам нужен
PRIMARY KEY
или UNIQUE
в таблице. Ключевое слово
REPLACE
заменяет старые записи на новые, когда новая запись
дублирует старую запись на уникальном значении ключа.
Если Вы получаете проблемы эффективности при создании копий на Вашей системе, можно решить их установкой репликации и созданием копий на подчиненной системе вместо главной. Подробности есть в разделе 4.10.1 Введение в репликацию.
Если Вы используете файловую систему Veritas, Вы можете делать следующее:
FLUSH TABLES WITH READ LOCK
mount vxfs
snapshot
.
UNLOCK TABLES
BACKUP TABLE
BACKUP TABLE tbl_name[,tbl_name...] TO '/path/to/backup/directory'
Эта команда делает копию всех файлов таблицы в резервный каталог, что
является минимумом, необходимым, чтобы восстановить ее. Сейчас это работает
только для таблиц MyISAM
. Для них копируются файлы
.frm
(определение) и .MYD
(данные). Индексный файл
может быть восстановлен из этих двух.
Перед использованием этой команды, пожалуйста, ознакомьтесь с разделом "4.4.1 Резервирование баз данных".
Пока таблица резервируется, она блокируется. Если нужно резервировать
сразу несколько таблиц, выполните команду LOCK TABLES
для каждой
таблицы в этой группе.
Команда возвращает таблицу со следующими столбцами:
Столбец | Значение |
Table | Имя таблицы |
Op | Обязательно ``backup'' |
Msg_type | Одно из status , error ,
info или warning . |
Msg_text | Собственно сообщение. |
Обратите внимание, что команда BACKUP TABLE
доступна только в
MySQL версии 3.23.25 и старше.
RESTORE TABLE
RESTORE TABLE tbl_name[,tbl_name...] FROM '/path/to/backup/directory'
Восстанавливает таблицу из копии, которая была сделана с помощью
BACKUP TABLE
. Существующие таблицы не будут перезаписаны, если
Вы попробуете восстанавливать существующую таблицу, получите ошибку.
Восстановление занимает больше времени, чем резервирование из-за
необходимости сгенерировать индексный файл. Чем больше имеется ключей, тем
дольше система будет его строить. Также, как и BACKUP TABLE
, эта
функция работает только с таблицами MyISAM
.
Команда возвращает таблицу со следующими столбцами:
Столбец | Значение |
Table | Имя таблицы |
Op | Обязательно ``restore'' |
Msg_type | Одно из status , error ,
info или warning . |
Msg_text | Собственно сообщение. |
CHECK TABLE
CHECK TABLE tbl_name[,tbl_name...] [option [option...]] option = QUICK | FAST | MEDIUM | EXTENDED | CHANGED
CHECK TABLE
работает только с таблицами типа
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
нет, Вы должны выполнить ремонт
таблицы. Подробности в разделе "
4.4.6 Использование myisamchk
для устранения повреждений".
Сообщение Not checked
говорит о том, что для данной таблицы
TYPE
сообщил MySQL, что там не было никакой потребности
проверять таблицу.
Различные типы проверки:
Тип | Значение |
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
отметит таблицу как ok.
Если таблица разрушена, то наиболее вероятное, что проблема находится в индексах, а не в части данных. Все приведенные выше типы проверки тестируют индексы и должны таким образом найти большинство ошибок.
Если Вы хотите только проверить таблицу, Вы не должны использовать никакие
параметры проверки или опцию QUICK
. Последний должен
использоваться, когда Вы спешите и можете позволить пропустить то малое число
ошибок, которое QUICK
не находит. Например, это ошибка в файле
данных. В большинстве случаев MySQL, при нормальном использовании, должен сам
найти любую ошибку в файле данных. Если это случается, таблица будет отмечена
как 'разрушено', тогда таблица не сможет использоваться, пока ошибка не
восстановлена, чтобы не развалить данные окончательно.
FAST
и CHANGED
обычно предназначены, чтобы
использоваться из скрипта (например, из cron), если Вы хотите проверять
таблицу время от времени. В большинстве случаев FAST
имеет
приоритет перед CHANGED
.
EXTENDED
должен использоваться после того, как Вы выполнили
нормальную проверку, но все еще получаете странные ошибки из таблицы, когда
MySQL пробует модифицировать строку или найти строку по ключу (это ОЧЕНЬ
маловероятно, если нормальная проверка прошла спокойно!).
Некоторые вещи, сообщаемые проверкой таблиц, не могут быть исправлены в автоматическом режиме:
Найденная строка, где столбец auto_increment имеет значение 0
. Это означает, что Вы имеете в таблице строку, где столбец индекса
auto_increment
содержит значение 0. Можно создать такую
конструкцию командой UPDATE
.
Это не ошибка само по себе, но может вызывать проблему, если Вы сбрасываете
таблицу в дамп, а потом восстановите ее оттуда или скомандуете
ALTER TABLE
на таблице. В этом случае столбец auto_increment
изменит значение, согласно правилам auto_increment, что может вызвать
проблемы подобно ошибке дублирования ключа.
Избавиться от предупреждения можно, только выполнив инструкцию
UPDATE
, чтобы установить столбец к некоторому другому значению
(не 0).REPAIR TABLE
REPAIR TABLE tbl_name[,tbl_name...] [QUICK] [EXTENDED]
REPAIR TABLE
тоже работает только на таблицах типа
MyISAM
и аналогичен вызову myisamchk -r table_name
.
Обычно Вам никогда не придется выполнять эту команду, но в случае ошибок
Вы, очень вероятно, вернете все Ваши данные из таблицы MyISAM с помощью
команды REPAIR TABLE
. Если Ваши таблицы разрушаются, Вы должны
попробовать нахйти причину этого! Подробности по этому вопросу есть в разделе
"8.4.1 Что делать, если MySQL рухнул".
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
для устранения поврежденийНачиная с MySQL 3.23.13, можно проверять таблицы MyISAM
командой CHECK TABLE
. Подробности в разделе
"4.4.4 Синтаксис CHECK TABLE
". Ремонтировать таблицы можно командой REPAIR TABLE
. Она
подробно рассмотрена в разделе "4.4.5
Синтаксис REPAIR TABLE
".
Для проверки и ремонта таблиц MyISAM (файлы с расширениями
.MYI
и .MYD
) можно использовать утилиту
myisamchk
. Для проверки и ремонта таблиц ISAM
(файлы с расширениями .ISM
и .ISD
) следует
пользоваться утилитой isamchk
. Подробности в разделе
"7 Типы таблиц MySQL".
Далее обсуждается myisamchk
, но вся информация также
применима к старой программе isamchk
.
Вы можете использовать myisamchk
, чтобы получать информацию
относительно ваших таблиц базы данных, проверять их, ремонтировать или
оптимизировать. Следующие разделы описывают, как вызвать
myisamchk
(включая описание опций), как установить план
сопровождения таблицы, и как использовать myisamchk
, чтобы
выполнить различные функции.
Вы в большинстве случаев можете также использовать команду OPTIMIZE
TABLES
, чтобы оптимизировать и ремонтировать таблицы, но это не так
быстро и надежно (в случае реальных фатальных ошибок) как
myisamchk
. С другой стороны, OPTIMIZE TABLE
проще.
Подробности в разделе "4.5.1 Синтаксис
OPTIMIZE TABLE
".
myisamchk
myisamchk
вызывается в общем виде так:
shell> myisamchk [options] tbl_name
Здесь options
указывает требуемые действия. Они описаны ниже
(Вы также можете получить список параметров вызовом
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 М свободного места.
Обратите внимание, что, если Вы получаете ошибку подобную:
myisamchk: warning: 1 clients is using or hasn't closed the table properly
Это означает, что Вы пробуете проверять таблицу, которая модифицируется
другой программой (подобно серверу mysqld
), которая не закрыла
файл или не может закрыть файл правильно.
Если запущен mysqld
, следует принудительно закрыть и сбросить
на диск все таблицы командой FLUSH TABLES
и гарантировать, что
никто не использует таблицы в то время, как Вы выполняете
myisamchk
. В MySQL Version 3.23 самый простой способ избежать
этой проблемы состоит в том, чтобы использовать CHECK TABLE
вместо myisamchk
, чтобы проверить таблицы.
myisamchk
Утилита myisamchk
поддерживает опции:
-# или --debug=debug_options
debug_options
обычно
является строкой в формате d:t:o,filename
.
-? или --help
-O var=option, --set-variable var=option
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 |
key_buffer_size
используется только при проверке таблицы с
опцией --extended-check
или восстановлении с опцией
-o
. sort_buffer_size
используется при
восстановлении таблицы с опцией --recover
.
Если Вы хотите ускорить восстановление, установите вышеупомянутые переменные в 1/4 доступной памяти. Вы можете устанавливать обе переменные в большие значения, так как только один из вышеупомянутых буферов будет использоваться в каждый момент времени. Восстановление через буфер ключей используется в следующих случаях:
--safe-recover
.
CHAR
, VARCHAR
или
TEXT
, поскольку алгоритм сортировки должен сохранять целые ключи
в течение сортировки. Если Вы имеете много свободного места, можно применить
опцию --sort-recover
.-s или --silent
-ss
.
-v или --verbose
-vv
или
-vvv
). Удобно использовать вместе с опциями -d
и
-e
.
-V или --version
myisamchk
.
-w или --wait
mysqld
на таблице с параметром
--skip-locking
, таблица может быть блокирована только другой
командой myisamchk
.myisamchk
-c или --check
myisamchk
никаких параметров, которые ее отменят.
-e или --extended-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
-U или --update-state
--check-only-changed
, но Вы не должны использовать это,
если mysqld
использует таблицу и запущен с параметром
--skip-locking
.
-T или --read-only
myisamchk
, чтобы проверить таблицу, которая находится в
использовании некоторой другой прикладной программой, которая не использует
блокировку (подобно mysqld --skip-locking
).Следующие параметры используются, если Вы запускаете
myisamchk
с опцией -r
или -o
:
-D # или --data-file-length=#
-e или --extend-check
-f или --force
table_name.TMD
)
вместо прерывания выполнения.
-k # или keys-used=#
#
индексов. Если Вы используете
MyISAM
, сообщает, какие ключи использовать, здесь каждый бит
соответствует ключу (первый ключ в бите 0). Это может использоваться, чтобы
получить ускорение вставки. Дезактивированные индексы могут быть повторно
активизированы, используя myisamchk -r
.
-l или --no-symlinks
myisamchk
восстанавливает таблицу, на которую указывают ссылки.
-r или --recover
-o
. Обратите
внимание, что в том маловероятном случае, когда -r
не может
помочь, файл данных все еще цел). Если Вы имеете много памяти, увеличьте
sort_buffer_size
!
-o или --safe-recover
-r
, но может обрабатывать ряд очень
маловероятных случаев, которые -r
не по зубам. Этот метод
восстановления также использует намного меньше дискового пространства, чем
-r
. Обычно нужно всегда сначала попробовать -r
и
только, если эта попытка провалилась, использовать -o
. Если Вы
имеете много памяти, увеличьте key_buffer_size
!
-n или --sort-recover
--character-sets-dir=...
--set-character-set=name
-t или --tmpdir=path
myisamchk
использует системную переменную TMPDIR
.
-q или --quick
-q
, чтобы myisamchk
изменял первоначальный
файл данных в случае двойных ключей.
-u или --unpack
myisamchk
Другие действия, которые myisamchk
может делать, помимо
ремонта и проверки таблиц:
-a или --analyze
-d или --description
-A или --set-auto-increment[=value]
-S или --sort-index
-R или --sort-records=#
SELECT
и ORDER BY
на этом индексе. Правда,
первая сортировка ОЧЕНЬ медленная. Чтобы узнать индексные числа таблицы,
используйте SHOW INDEX
, эта команда показывает индексы таблицы в
том порядке, в каком их видит myisamchk
. Индексы пронумерованы,
начиная с 1, а не с 0.myisamchk
Распределение памяти важно, когда Вы выполняете myisamchk
.
myisamchk
использует не больше памяти, чем ему разрешено
параметром -O
. Если Вы собираетесь использовать
myisamchk
на очень больших файлах, Вы должны сначала решить,
сколько памяти Вы можете ему выделить (лучше по максимуму). Значение по
умолчанию составляет около 3 мегабайт для исправления ошибок. Используя
большие значения, Вы можете ускорить работу myisamchk
. Например,
если Вы имеете больше, чем 32M RAM, Вы могли бы использовать параметры типа
этих (в дополнение к любым другим параметрам, которые Вы определили):
shell> myisamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...
Использование -O sort=16M
достаточно для большинства случаев.
Знайте, что myisamchk
использует временные файлы в
TMPDIR
. Если TMPDIR
указывает на файловую систему
памяти, Вы можете легко получить ошибку переполнения памяти. Если это
случается, установите 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
.
myisamchk
для ремонта
Если Вы выполняете mysqld
с опцией
--skip-locking
(это является значением по умолчанию на некоторых
системах, подобно Linux), Вы не может надежно использовать
myisamchk
, чтобы проверить таблицу, когда mysqld
использует ту же самую таблицу. Если Вы можете убедиться, что никто не
обращается к таблицам через mysqld
в то время, как Вы выполняете
myisamchk
, Вы должны сделать только
mysqladmin flush-tables
прежде, чем начать проверять таблицы.
Если Вы не можете гарантировать вышеупомянутое, следует завершить
mysqld
перед проверкой таблиц. Если Вы выполняете
myisamchk
в то время, как mysqld
модифицирует
таблицы, Вы можете получить предупреждение, что таблица разрушена, даже если
это не так.
Если Вы не используете опцию --skip-locking
, Вы можете
использовать myisamchk
, чтобы проверить таблицы в любое время.
Пока Вы это делаете, вся клиентура, которая пробует модифицировать таблицу,
будет ждать завершения проверки.
Если Вы используете myisamchk
для ремонта или оптимизируете
таблицы, Вы ДОЛЖНЫ всегда гарантировать, что сервер
mysqld
не использует таблицу (это также применяется, если Вы
используете --skip-locking
). Если Вы не завершаете
mysqld
, нужно по крайней мере скомандовать
mysqladmin flush-tables
перед запуском myisamchk
.
Эта глава описывает, как проверять таблицы и иметь дело с нарушением целостности данных (не индексов) в базах данных MySQL. Если Ваши таблицы разрушились, Вы должны попробовать найти причину этого! Подробности в разделе "8.4.1 Что делать, если MySQL рухнул".
Формат файлов, в которых MySQL хранит свои таблицы, очень надежен, но всегда бывают случаи, когда таблицы будут подпорчены:
mysqld
рухнул посреди сеанса записи.
При выполнении восстановления важно понять, что каждая таблица
tbl_name
в базе данных соответствует трем файлам в
каталоге баз данных:
Файл | Зачем он нужен |
tbl_name.frm | Определение таблицы (форма) |
tbl_name.MYD | Данные таблицы |
tbl_name.MYI | Индексный файл таблицы |
Каждый из этих трех файлов портится различными способами, но проблемы происходят наиболее часто в файлах данных и индексных файлах.
myisamchk
работает, создавая копию .MYD (файлов с
данными) строка в строку. Он заканчивает стадию ремонта, удаляя старый файл
.MYD и переименовывая новый файл к первоначальному имени файла.
Если Вы используете опцию --quick
, myisamchk
не
создает временный файл .MYD, а принимает, что файл .MYD
правилен и только генерирует новый индексный файл без того, чтобы затронуть
соответствующий ему файл .MYD. Это безопасно потому, что
myisamchk
автоматически обнаруживает повреждение файла
.MYD и прерывает ремонт в этом случае. Вы можете также давать два
параметра --quick
. В этом случае myisamchk
не
прерывается на некоторых ошибках (подобно двойному ключу), но взамен пробует
решать их, изменяя файл .MYD. Обычно использование двух параметров
--quick
нужно только, если Вы имеете слишком мало свободного
дискового пространства, чтобы выполнить нормальный ремонт. В этом случае Вы
должны по крайней мере сделать копию перед запуском myisamchk
.
Для проверки таблиц MyISAM используйте следующие команды:
myisamchk tbl_name
myisamchk
без параметров или с параметрами
-s
или --silent
.
myisamchk -m tbl_name
myisamchk -e tbl_name
-e
означает "extended
check" или расширенную проверку). Выполняется тестовое чтение каждого ключа
для каждой строки, чтобы проверить, что они в самом деле указывают на
правильную строку. Это может занять МНОГО времени на большой таблице с
богатым ассортиментом ключей. Здесь надо отметить, что myisamchk
будет обычно останавливаться после первой ошибки, которую он найдет. Если Вы
хотите получить большее количество информации, Вы можете добавлять опцию
--verbose
(-v
). Это заставляет
myisamchk
работать первые 20 ошибок. При нормальном
использовании простого вызова myisamchk
(без параметров, кроме
имени таблицы) достаточно.
myisamchk -e -i tbl_name
-i
предписывает, чтобы
myisamchk
напечатал также и некоторую информационную статистику.
Здесь я расскажу о ремонте таблиц системы MyISAM
(расширения
файлов .MYI
и .MYD
). Для этого потребуется
программа myisamchk
. При использовании таблиц системы
ISAM
(их файлы имеют расширения .ISM
и
.ISD
), следует использовать программу isamchk
.
Признаки разрушенной таблицы обычно выглядят как неожиданное завершение работы во время запроса и появление ошибок типа:
perror ###
. Вот наиболее распространенные ошибки и
соответствующие им коды (заметьте, что можно указывать несколько кодов ошибок
подряд, разделяя их пробелами):
shell> perror 126 127 132 134 135 136 141 144 145 126 = Индексный файл разрушен или неверный формат файла 127 = Файл записей разрушен 132 = Старый файл базы данных 134 = Запись уже удалена (возможно, файл записей разрушен) 135 = Нет места в файле записей 136 = Нет места в индексном файле 141 = Дублирование уникального ключа или запрет на запись/обновление 144 = Таблица разрушена, и последний ремонт провалился 145 = Таблица была помечена как разрушеная и успешно отремонтированаВнимаение: ошибка 135 (нет места в файле записей) не может быть устранена простым ремонтом. В случае ее возникновения надо скомандовать:
ALTER TABLE table MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;
Во всех остальных случаях Вы должны отремонтировать Ваши таблицы.
Программа myisamchk
может обычно обнаружить и устранить
большинство встречающихся ошибок.
Процесс ремонта включает до четырех стадий, описанных ниже. Прежде, чем Вы
начнете ремонт, надлежит перейти командой cd
в каталог баз
данных и проверить разрешения файлов таблицы. Удостоверьтесь, что они читаемы
тем пользователем, от имени которого выполняется mysqld
(и Вами
потому, что Вы должны обратиться к файлам, которые Вы проверяете). Если
окажется, что Вы должны изменить файлы, они должны также быть перезаписываемы
Вами, то есть Вы должны иметь право на запись.
Если Вы используете MySQL 3.23.16 и выше, то Вы можете
пользоваться командами CHECK
и REPAIR
для проверки
и восстановления таблиц системы MyISAM
соответственно.
Подробности в разделах "4.4.4 Синтаксис
CHECK TABLE
" и "4.4.5
Синтаксис REPAIR TABLE
".
Раздел об администрировании таблиц включает в себя подробное описание
всех необходимых для ремонта и проверки параметров. Подробности в разделе
"4.4.6 Использование
myisamchk
для устранения повреждений".
Следующий раздел предназначен для случаев, когда вышеупомянутая команда терпит неудачу, или если Вы хотите использовать расширенные свойства, которые предоставляются утилитами isamchk/myisamchk.
Если Вы выполняете ремонт таблиц из командной строки, сначала завершите
сервер mysqld
. Обратите внимание, что, когда Вы даете команду
mysqladmin shutdown
на удаленной системе, mysqld
будет работать некоторое время после mysqladmin
, пока все
запросы не будут остановлены, и все ключи сброшены на диск.
Стадия 1: Проверка Ваших таблиц
Запустите myisamchk *.MYI
или
(myisamchk -e *.MYI
, если Вы имеете много времени). Используйте
опцию -s
(тихий режим работы), чтобы подавить вывод ненужной
технической информации.
Если сервер mysqld выполнен, Вы должны использовать опцию --update, чтобы
myisamchk
отметил таблицу как 'проверено'.
Вы должны ремонтировать только те таблицы, для которых
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
. Безопасный режим
восстановления использует старый метод восстановления, который обрабатывает
несколько случаев, не поддающихся обычной процедуре ремонта (зато работает
куда медленнее).Стадия 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
должен бы
сработать нормально (это не должно быть бесконечным циклом).
Стадия 4: Очень трудный ремонт
Если Вы дошли до этой точки, значит файл-описание тоже разрушен. Плохо дело... Этого вообще-то никогда не должно случиться, потому что файл описания после того, как таблица создана, не изменяется.
myisamchk -r
.
Из-за фрагментации записей и удаления данных возникает много пустого
места в файле таблиц. Запустите myisamchk
в режиме
восстановления для его зачистки:
shell> myisamchk -r tbl_name
Вы можете оптимизировать таблицу, используя инструкцию SQL OPTIMIZE
TABLE
. OPTIMIZE TABLE
ремонтирует таблицы, анализирует
ключи и сортирует индексное дерево, чтобы создать более быстрые поисковые
таблицы ключей. Совместная работа утилиты и сервера ничему не повредит, так
как сервер имеет доступ к таблице, а ее сортировка идет в фоновом режиме.
Подробности в разделе "4.5.1 Синтаксис
OPTIMIZE TABLE
".
Утилита myisamchk
также имеет ряд дополнительных параметров,
которые Вы можете использовать, чтобы улучшить эффективность таблицы:
-S, --sort-index
-R index_num, --sort-records=index_num
-a, --analyze
Полное описание опций приведено в разделе
"4.4.6.1 Синтаксис обращения к
myisamchk
".
Начиная с MySQL 3.23.13 Вы можете проверять таблицы
MyISAM командой CHECK TABLE
. Подробности в разделе
"4.4.4 Синтаксис
CHECK TABLE
". Ремонтировать таблицы можно командой
REPAIR TABLE
. Подробности в разделе
"4.4.5 Синтаксис
REPAIR TABLE
".
Неплохо проверять таблицы время от времени в целях профилактики, не
дожидаясь, пока Ваша база данных взорвется. В этих целях рекомендуется
использовать myisamchk -s
для проверки таблиц. Опция
-s
предписывает myisamchk
докладывать только
об ошибках в случае их обнаружения.
Имеет смысл выполнять проверку при запуске сервера. Например, если
компьютер перезагрузили посреди обращения к базе данных, надо при загрузке
сервера проверить все таблицы, на которые можно было бы воздействовать
(известны как ``expected crashed table''). Вы могли бы добавлять тест к
safe_mysqld
, который выполняет myisamchk
, чтобы
проверить все таблицы, которые изменились в течение последних 24 часов, если
имеется старый файл `.pid' (process ID), оставшийся после
перезагрузки. Файл `.pid' создается при запуске mysqld
и автоматически удаляется при нормальном завершении. Присутствие
`.pid' при запуске системы указывает, что mysqld
был
завершен неправильно.
Нужно проверить все таблицы, чье время модификации позже, чем у этого файла `.pid'.
Вы должны также проверять таблицы регулярно при нормальной работе
системы. Например, еженедельную проверку можно поручить планировщику задач
cron
, добавив строку в файл crontab:
35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI
Эта команда выведет данные о поврежденных таблицах, так что их можно будет проверить, когда будет такая возможность.
Для полной уверенности рекомендуется командой myisamchk -s
проверять раз в сутки все таблицы, которые изменились за это время.
Чтобы получить описание таблицы или статистику по ней, используйте команды, показанные ниже.
myisamchk -d tbl_name
myisamchk
в режиме описания (``describe mode''),
чтобы произвести описание Вашей таблицы. Если Вы запускаете сервер
MySQL с опцией --skip-locking
,
myisamchk
может выдать ошибку для таблицы, которая
модифицируется во время его выполнения. Однако, поскольку
myisamchk
не вносит изменений в таблицу в режиме описания, то
повредить ее он не может.
myisamchk -d -v tbl_name
myisamchk -eis tbl_name
myisamchk -eiv tbl_name
-eis
, но сообщает Вам, что сделается.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 [LOTS OF ROW NUMBERS DELETED] Records: 1403698 M.recordlength: 226 Packed: 0% Recordspace used: 100% Empty space: 0% Blocks/Record: 1.00 Record blocks: 1403698 Delete blocks: 0 Recorddata: 317235748 Deleted data: 0 Lost space: 0 Linkdata: 0 User time 1639.63, System time 251.61 Maximum resident set size 0, Integral resident set size 0 Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0 Blocks in 4 out 0, Messages in 0 out 0, Signals 0 Voluntary context switches 10604, Involuntary context switches 122798
Размеры файлов данных и индекса, использованных в этих примерах:
-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
Теперь немного о терминологии, использованной в этом выводе. Здесь "keyfile" означает индексный файл. "Record" и "row" являются синонимами.
ISAM file
Isam-version
Creation time
Recover time
Data records
Deleted blocks
Datafile: Parts
Data records
.
Deleted data
Datafile pointer
Keyfile pointer
Max datafile length
.MYD
).
Max keyfile length
.MYI
).
Recordlength
Record format
Фиксированную длину (Fixed length)
. Другие
возможные значения: Сжатый (Compressed)
и Упакованный
(Packed)
.
table description
Key
Start
Len
Index
Уникальный (unique)
или множественный (multip)
.
Указывает, может ли одно значение существовать многократно в этом индексе.
Type
packed
, stripped
или empty
.
Root
Blocksize
Rec/key
myisamchk -a
.
Если это не модифицируется вообще, значение по умолчанию 30.
Keyblocks used
myisamchk
,
значения очень высоки (очень близки к теоретическому максимуму).
Packed
CHAR
/
VARCHAR
/DECIMAL
. Для длинных строк это может
существенно экономить место. В третьем примере выше четвертый ключ длиной 10
символов, и на нем достигнуто уменьшение в 60%.
Max levels
Records
M.recordlength
Packed
Packed
указывает, сколько процентов на этом сэкономлено.
Recordspace used
Empty space
Blocks/Record
myisamchk
. Подробности в разделе
"4.4.6.10 Оптимизация таблиц".
Recordblocks
Deleteblocks
Recorddata
Deleted data
Lost space
Linkdata
Linkdata
равна сумме
памяти, используемой всеми такими указателями.Если таблица была сжата с помощью myisampack
, то команда
myisamchk -d
выведет дополнительную информацию относительно
каждого столбца таблицы. Подробности в разделе
"4.7.4 Генератор сжатых таблиц MySQL
только для чтения".
Эта глава описывает различные свойства репликации в MySQL. Здесь рассказано о том, как использовать поддержку репликации баз данных, какие проблемы могут быть, как их решать.
Репликация может помочь резко ускорить работу и повысить ошибкоустойчивость. Для ошибкоустойчивости Вы можете иметь две системы и обращаться к копии, если Вы имеете проблемы с главной системой. Быстродействие улучшается за счет переброски части запросов, не модифицрующих данные, на второй сервер. Конечно, это работает только, если такие запросы доминируют, но это нормальный случай.
Начиная с Version 3.23.15, MySQL поддерживает одностороннюю репликацию. Один сервер действует как главный (master), остальные как подчиненные (slave). Обратите внимание, что один сервер может выполнять обе роли сразу. Главный сервер хранит двоичный файл регистрации модификаций (подробности в разделе "4.9.4 Двоичный протокол изменений ") и индексный файл к двоичным файлам регистрации, чтобы следить за циклическим сдвигом файла регистрации. Подчиненный докладывает главному о том, где он остановился после последней успешной модификации. обновляет свои данные, блокирует базу данных и ждет новых обновлений.
Обратите внимание, что если Вы копируете базу данных, все модификации для этой базы данных должны быть выполнены через главный сервер!
Другая польза от использования репликации в том, что главный сервер может заниматься только обслуживанием запросов, а резервирование можно выполнять на подчиненном. Подробности в разделе "4.4.1 Резервирование баз данных".
Репликация в MySQL основана на сервере, следящем за всеми изменениями для базы данных (модификации, удалении и т.д) в двоичном файле регистрации, и подчиненном сервере (их может быть несколько штук), читающем сохраненные запросы из двоичного файла регистрации так, чтобы подчиненный мог выполнять те же самые запросы на своей копии данных.
Очень важно понять, что двоичный файл регистрации всего лишь запись, начинающаяся с фиксированной отметки во времени (момент, когда Вы запустили двоичную регистрацию). Любые подчиненные системы, которых Вы установили, будут нуждаться в копиях всех данных с главного сервера потому, что существовал момент, когда Вы запустили двоичную регистрацию на нем. Если Вы запускаете подчиненные системы не с теми данными, которые были на главном сервере на момент начала протоколирования, все это провалится.
Запущенный подчиненный сервер будет связываться с главным и получать
данные по изменениям. Если связь оборвалась, подчиненный будет пытаться ее
восстановить через каждые master-connect-retry
секунд.
Каждый подчиненный сам следит, где именно прекратились обновления. Главный сервер не знает ни того, сколько подчиненных серверов работают, ни тем более того, какой из них чем занят.
Нижеследующее представляет собой быстрое описание того, как установить полную поддержку репликации на работающем сервере MySQL. Здесь считается, что Вы хотите копировать все Ваши базы данных и не конфигурировали репликацию ранее. Сервер на некоторое время придется завершить для выполнения работ.
FILE
и разрешением соединяться от имени всех
подчиненных систем. Если пользователь только делает репликацию (что очень
рекомендуется!), Вы не должны предоставлять ему дополнительные привилегии.
Например, чтобы создать пользователя с именем repl
, который
может обращаться к Вашему главному компьютеру с любого другого компьютера, Вы
могли бы использовать эту команду:
GRANT FILE ON *.* TO repl@"%" IDENTIFIED BY '<password>';
mysqladmin -u root -p<password> shutdown
tar -cvf /tmp/mysql-snapshot.tar /path/to/data-dirWindows-пользователям рекомендуется использовать для этих целей WinZip или что-то подобное, впрочем, версии tar есть под всеми известными мне ОС. Windows тут не исключение.
my.cnf
на главном сервере добавьте строки
log-bin
и server-id=unique number
в секцию
[mysqld]
. Очень важно, что идентификаторы подчиненных отличаются
от идентификатора главной системы.
[mysqld] log-bin server-id=1
my.cnf
надлежит дописать:
master-host=<hostname of the master> master-user=<replication user name> master-password=<replication user password> master-port=<TCP/IP port for master> server-id=<some unique number between 2 and 2^32-1>Значения в <> следует заменить на соответствующие Вашей системе.
server-id
должен быть свой для каждой машины, участвующей в
репликации. Если Вы не определяете идентификатор сервера, он будет установлен
в 1, если Вы не определили master-host
, иначе он будет
установлен в значение 2. Обратите внимание, что в случае вычеркивания
идентификатора server-id
главный сервер откажется от подключений
от всех подчиненных машин, а они не смогут связаться с ним.
После того, как Вы сделали вышеупомянутое, подчиненный должен соединиться с главным сервером и получить все обновления, которые были произведены с момента резервирования данных.
Если Вы забыли установить идентификатор (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.info
в том же самом каталоге, где и файл регистрации
ошибок. Файл master.info
используется подчиненным, чтобы
следить, что из двоичного файла регистрации главного сервера он уже
обработал. Не удаляйте и не правьте файл, если Вы не знаете точно, что и
зачем Вы делаете. Даже если знаете, лучше пользуйтесь командой CHANGE
MASTER TO
.
Что поддерживается, а что еще нет? Здесь я рассматриваю краткий перечень проблем и возможностей репликации. Итак, начнем:
AUTO_INCREMENT
,
LAST_INSERT_ID
и значениями TIMESTAMP
.
RAND()
в модификациях не копируется правильно. Используйте
RAND(some_non_rand_expr)
, если Вы копируете модификации с
RAND()
. Вы можете, например, использовать
UNIX_TIMESTAMP()
как аргумент для RAND()
.
--default-character-set
) на главной и подчиненных машинах. Если
это не так, Вы можете получать ошибки дублирования ключей на подчиненном
потому, что ключ, который расценен как уникальный на главной системе, не
может быть таким в другом наборе символов.
LOAD DATA INFILE
будет обработан правильно, пока файл все
еще существует на главной машине во время распространения модификации. Зато
LOAD LOCAL DATA INFILE
будут пропущены.
FLUSH
не сохраняются в двоичном файле регистрации и
из-за этого не копируются на подчиненные машины. Это обычно не проблема,
поскольку FLUSH
ничего не меняет в данных. Но если Вы
модифицируете таблицы привилегий MySQL
непосредственно без того,
чтобы использовать инструкцию GRANT
, и затем Вы копируете
базу данных привилегий MySQL
, Вы должны отдать команду
FLUSH PRIVILEGES
на подчиненных, чтобы новые версии привилегий
вступили в законную силу.
SLAVE STOP
, затем проверьте переменную
Slave_open_temp_tables
, чтобы увидеть, является ли она 0, потом
скомандуйте mysqladmin shutdown
. Если переменная не равна 0,
перезапустите подчиненный процесс SLAVE START
и попробуйте еще.
В версии 4.0 обещали как-то это уладить, но пока так и не сделали. В более
ранних версиях временные таблицы вообще не копируются правильно. Я
рекомендую, чтобы Вы или нарастили вычислительные возможности, или выполнили
SET SQL_LOG_BIN=0
на всех клиентах перед всеми запросами с
участием временных таблиц.
log-slave-updates
. Обратите
внимание, что ряд запросов не будет корректно функционировать в этом виде
установки, если ваш код пользователя не учитывает потенциальных проблем,
которые могут произойти от модификаций, которые происходят в различной
последовательности на разных серверах. Это означает, что Вы можете делать
установку подобно следующему:
A -> B -> C -> AЭта установка будет работать только, если Вы не делаете противоречивые модификации между таблицами. Другими словами, если Вы вставляете данные A и C, Вы никогда не должны вставлять строку в A, который может иметь противоречивый ключ со вставкой строки в C. Вы не должны также модифицировать строки на двух серверах, если порядок, в котором применяются модификации, может быть неправильным. Обратите внимание, что формат файла регистрации изменился в версии 3.23.26 так, что pre-3.23.26 его не поймет.
.err
файле. Вы должны затем
соединиться с подчиненным вручную, установить причину ошибки (например,
несуществующая таблица) и выполнить команду sql SLAVE START
(доступна с весрии 3.23.16). В версии 3.23.15 Вы должны перезапустить сервер,
master-connect-retry
(по умолчанию 60) секунд. Из-за этого можно безопасно завершать работу
главного сервера, а затем перезапускать его через некоторое время.
master-port
в файле my.cnf
.
replicate-do-db
в my.cnf
или исключать
набор баз данных директивой replicate-ignore-db
. Обратите
внимание, что вплоть до версии 3.23.23 имелась ошибка, которая не давала
правильно работать с LOAD DATA INFILE
, если Вы использовали это
в базе данных, которая была исключена из репликации.
SET SQL_LOG_BIN=0
выключит
двоичный протокол на главном сервере, а SET SQL_LOG_BIN=1
все
вернет на свои места. Для этого Вы должны иметь привилегию process.
FLUSH MASTER
и FLUSH SLAVE
. В
версии 3.23.26 они переименованы в RESET MASTER
и RESET
SLAVE
соответственно, чтобы разъяснить то, что они делают. Старые
варианты FLUSH
тем не менее все еще работают для совместимости.
LOAD TABLE FROM
MASTER
для сетевого резервирования и начала репликации. На момент
написания книги, эта функция была нестабильной и находилась в стадии отладки.
CHANGE MASTER TO
.
binlog-ignore-db
.
replicate-rewrite-db
, чтобы сообщить подчиненному о том, что
надо применять модификации из одной базы данных на главной системе к базе
данных с другим именем на подчиненном.
PURGE MASTER LOGS
TO log-name
, чтобы избавиться от старых файлов регистрации в то
время, как подчиненный продолжает работать.Если Вы пользуетесь репликацией, используйте минимум MySQL Version 3.23.30 (а лучше выше). Старые версии работают, но глюков там хватает...
На главной и подчиненной системах нужно использовать опцию
server-id
. Она устанавливает уникальный идентификатор. Вы должны
выбрать уникальное значение в диапазоне от 1 до 2^32-1. Например:
server-id=3
Следующая таблица показывает параметры, которые Вы можете использовать для главного (MASTER) сервера:
Опция | Описание |
log-bin=filename | Записывать в двоичный файл
регистрации модификаций filename. Обратите внимание, что, если Вы задаете
этот параметр с расширением (например,
log-bin=/mysql/logs/replication.log ) версии до 3.23.24 не будут
работать корректно, если Вы делаете FLUSH LOGS . Проблема была
исправлена в версии 3.23.25. Если Вы используете этот вид имени файла
регистрации, команды FLUSH LOGS будут игнорироваться. Чтобы
очистить файл регистрации, выполните FLUSH MASTER на главной
системе и FLUSH SLAVE на всех подчиненных. В версии 3.23.26 и в
более поздних Вы должны использовать RESET MASTER и RESET
SLAVE |
log-bin-index=filename | Поскольку пользователь
мог бы выдавать команду FLUSH LOGS Вы должны знать, который файл
регистрации является в настоящее время активным. Эта информация сохранена в
двоичном индексном файле регистрации. Значение по умолчанию `hostname`.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=some_database . |
binlog-ignore-db=database_name |
Сообщает главной системе, что модификации, где текущая база данных является
database_name, НЕ должны быть сохранены в двоичном файле регистрации.
Обратите внимание, что, если Вы используете эту опцию, Вы должны
гарантировать, что делаете модификации только в текущей базе данных.
Например: binlog-ignore-db=some_database |
Следующая таблица показывает параметры, которые Вы можете использовать для подчиненной (SLAVE) системы:
Опция | Описание |
master-host=host |
Имя хоста или IP-адрес главной системы. Если не задано, подчиненный не будет
работать вообще. Например: master-host=joker.botik.ru . |
master-user=username |
Пользователь под именем которого надо связываться с главной системой.
Пользователь должен иметь привилегию FILE . Если не задано,
принимается пользователь test . Например:
master-user=alexmv . |
master-password=password |
Пароль для пользователя из предыдущего параметра. По умолчанию принимается
пустой пароль. Например: master-password=pupsik . |
master-port=portnumber |
Порт для связи с главной системой. Если не задан, принимается компилируемая
установка MYSQL_PORT . Если Вы не меняли опции
configure , это будет 3306. Например:
master-port=3306 . |
master-connect-retry=seconds |
Число секунд, которые подчиненный будет бездействовать перед повторением
попытки восстановить связь с главной системой в случае ее обрыва. Значение по
умолчанию 60. Например: master-connect-retry=60 . |
master-ssl | Включить поддержку SSL. Например:
master-ssl . |
master-ssl-key | Имя файла с ключем SSL для
главной системы. Например: master-ssl-key=SSL/master-key.pem .
|
master-ssl-cert | Имя файла с сертификатом SSL для
главной системы. Например: master-ssl-key=SSL/master-cert.pem .
|
master-info-file=filename | Расположение файла,
который хранит данные о ходе процесса репликации. Значение по умолчанию
master.info в каталоге данных. Например:
master-info-file=master.info . |
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-ignore-db . Например:
replicate-ignore-table=db_name.some_table . |
replicate-wild-do-table=db_name.table_name |
Сообщает, чтобы подчиненная система ограничила репликацию таблицами, которые
соответствуют определенному образцу подстановочных знаков. Чтобы определять
больше, чем одну таблицу, используйте директиву несколько раз, по одному для
каждой таблицы. Это будет работать для модификаций с перекрестной базой
данных. Например: replicate-wild-do-table=foo%.bar% будет
копировать только модификации к таблицам во всех базах данных, которые
начинаются с foo и только для таблиц, имена которых начинаются с bar. |
replicate-wild-ignore-table=db_name.table_name | Противоположно предыдущей опции. |
replicate-ignore-db=database_name | Сообщает,
чтобы подчиненная система не копировала определенную базу данных. Чтобы
определять больше, чем одну базу, используйте директиву несколько раз, по
одному для каждой. Эта опция не будет работать, если Вы используете
перекрестные модификации базы данных. Если Вы нуждаетесь в перекрестных
модификациях базы данных, следует удостовериться, что Вы имеете версию
3.23.28 или позже, и использовать
replicate-wild-ignore-table=db_name.% . Например:
replicate-ignore-db=some_db . |
replicate-do-db=database_name | Сообщает, чтобы
подчиненная система ограничила репликацию определенной базой данных. Чтобы
определять больше, чем одну базу, используйте директиву несколько раз, по
одному для каждой. Эта опция не будет работать, если Вы используете
перекрестные модификации базы данных, то есть под запретом оказываются
запросы типа UPDATE some_db.some_table SET foo='bar' при выборе
иной база или не выбрано никакой. Если Вы нуждаетесь в перекрестных
модификациях базы данных, следует удостовериться, что Вы имеете версию
3.23.28 или позже, и использовать
replicate-wild-do-table=db_name.% . Например:
replicate-do-db=some_db . |
log-slave-updates | Сообщает, чтобы подчиненная система регистрировала модификации из подчиненного процесса в двоичном файле регистрации. По умолчанию Off. |
replicate-rewrite-db=from_name->to_name |
Обновлять базу данных с именем, отличным от первоначального. Например:
replicate-rewrite-db=master_db_name->slave_db_name . |
skip-slave-start | Сообщает, чтобы подчиненная
система не запускалась как подчиненная. Пользователь может запустить это
позже с помощью SLAVE START . |
slave_read_timeout=# | Число секунд, которое надо ждать перед разрывом связи. |
Реликация может контролироваться через интерфейс SQL.
Команда | Описание |
SLAVE START | Запустить подчиненный (Slave) поток. |
SLAVE STOP | Выключить подчиненный (Slave) поток. |
SET SQL_LOG_BIN=0 | Отключает регистрацию модификации, если пользователь имеет привилегию process. |
SET SQL_LOG_BIN=1 | Заново запускает регистрацию модификации, если пользователь имеет привилегию process. |
SET SQL_SLAVE_SKIP_COUNTER=n | Пропустить
следующие n событий от главной системы. Работает только, если
подчиненный не запущен, иначе выдает ошибку. Полезно при ремонте сбоев. |
RESET MASTER | Удаляет все двоичные файлы
регистрации, перечисленные в индексном файле, очищая индексный файл binlog. В
версиях до 3.23.26 называлась FLUSH MASTER |
RESET SLAVE | Подчиненный забывает позицию
репликации в главных файлах регистрации. В версиях до 3.23.26 называлась
FLUSH SLAVE |
LOAD TABLE tblname FROM MASTER | Загрузить копию таблицы с главной системы на подчиненную |
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 или из командной
строки. |
SHOW MASTER STATUS | Обеспечивает информацию состояния binlog главной системы. |
SHOW SLAVE STATUS | Обеспечивает информацию состояния существенных параметров подчиненной системы. |
SHOW MASTER LOGS |
Вносит в список двоичные протоколы на главной системе. Доступно с версии
3.23.28. Вы должны использовать эту команду до
PURGE MASTER LOGS TO . |
PURGE MASTER LOGS TO logname | Удаляет все файлы
регистрации репликаций, которые перечислены в индексе файла регистрации как
находящиеся до определенного файла регистрации, и затем удаляет их из индекса
файла регистрации так, чтобы данный файл регистрации теперь стал первым.
Доступно с версии 3.23.28. Пример:
PURGE MASTER LOGS TO mysql-bin.010Эта команда ничего не будет делать, если Вы имеете дело с активным подчиненным сервером, который в настоящее время читает один из файлов регистрации, которые Вы пробуете удалять. Команда безопасна для выполнения в то время, когда все подчиненные копируют данные. Сначала выясните, какие файлы обрабатывает каждый подчиненный командой SHOW SLAVE STATUS , затем выясните очередь протоколов на главной
системе командой SHOW MASTER LOGS , найдите самый старый протокол
на подчиненных, зарезервируйте все подготовленные к удалению протоколы, если
считаете это необходимым, и удалите все старые протоколы. |
Q:Почему я иногда вижу больше, чем один процесс
Binlog_Dump
на главном сервере после того, как я перезапустил
подчиненный ему сервер?
A: Binlog_Dump
непрерывный процесс, который
обрабатывается следующим способом:
pthread_cond_wait()
и
ждет появления обновлений или сигнала на завершение.
Binlog_dump
.
Так, если подчиненный процесс остановлен, соответствующий процесс
Binlog_Dump
на главной системе не будет обращать внимание на это
до окончания по крайней мере одной модификации. Тем временем, подчиненный
может открыть другое подключение, которое породит новый процесс
Binlog_Dump
...
Вышеупомянутая проблема не должна присутствовать в версии 3.23.26 и более
поздних версиях. В версии 3.23.26 добавили идентификатор
server-id
на каждый сервер репликации, и теперь все старые
процессы уничтожаются, когда новый процесс репликации соединяется с того же
самого подчиненного сервера.
Q: Как обеспечить ротацию файлов регистрации?
A: В версии 3.23.28 Вы должны использовать команду
PURGE MASTER LOGS TO
после определения того, которые файлы
регистрации могут быть удалены, и их предварительного факультативного
резервирования. В более ранних версиях процесс намного сложнее и не может
быть безопасно выполнен без выключения всех подчиненных систем. Вы должны
остановить подчиненные системы, отредактировать двоичный индексный файл
регистрации, удалить все старые файлы регистрации, перезапустить главную
систему, запустить подчиненные системы и затем удалить старые журналы.
Q: Как проводить апгрейд при работающей репликации?
A: Если Вы апгрейдитесь с версий pre-3.23.26, Вы должны
только блокировать главные таблицы, выполнить FLUSH MASTER
на
главной системе и FLUSH SLAVE
на остальных для перезапуска
протоколов. После этого надо перезапустить новые вресии на всех системах.
После версии 3.23.26 можно иметь разные версии MySQL на главной и подчиненной системах (не ниже 3.23.26). Дело в том, что теперь протокол связи для репликации утвержден и не меняется каждую версию.
Q: Какие проблемы я должен знать при установке двухсторонней репликации?
A: MySQL в настоящее время не поддерживает протокол блокировки между главным и подчиненным, чтобы гарантировать такую репликацию. На сегодняшний день при попытке такой репликации можно получить противоречивые таблицы, так что не следует этого делать.
Вы должны также понять, что двухсторонняя репликация фактически не улучшает эффективность работы.
Q: Как я могу использовать репликацию, чтобы улучшить эффективность моей системы?
A: Вы должны установить одну систему как главную,
направить на нее все процессы записи и настроить так много подчиненных, как
только можно, распределяя чтение между главной и подчиненными системами. Вы
можете также запустить подчиненных с опциями --skip-bdb
,
--low-priority-updates
и
--delay-key-write-for-all-tables
, чтобы получить рост
быстродействия. В этом случае подчиненный использует не транзакционные
таблицы MyISAM
вместо таблиц BDB
, чтобы получить
большее быстродействие.
Q: Как модифицировать клиентский код для использования всех прелестей репликации?
A: Для начала писать правильно. Куски клиентов, отвечающие за связь с базой данных, должны быть абстрактными и модульными. В этом случае надо только изменить реализацию Вашего доступа к базе данных так, чтобы читать из некоторого подчиненного или главного сервера, но писать всегда на главный. Если Ваш код не имеет этого уровня абстракции, установка репликации подтолкнет Вас к написанию правильного кода. Можно начать с создания библиотеки с функциями:
safe_writer_connect()
safe_reader_connect()
safe_reader_query()
safe_writer_query()
safe_
означает, что функция сама будет заботиться об
обработке всех ошибок. Конечно, имена функций можно использовать любые.
Вы должны затем преобразовать Ваш код пользователя, чтобы использовать эту
библиотеку. Это может быть сначала болезненным и страшным процессом, но со
временем окупится. Код будет намного проще, и добавление параметров поиска
неисправностей будет тривиально. Вы будете должны изменить только одну или
две-три функции. Если готового кода много, можно попробовать автоматизировать
преобразование с помощью утилиты Monty's replace
, которая входит
в стандартный дистрибутив MySQL, или написать свой скрипт на Perl. Хотелось
бы надеяться, что Ваш код следует за некоторым распознаваемым образцом.
Q: В каких случаях и насколько репликация может ускорить работу моего сервера MySQL?
A: Репликация MySQL наиболее полезна для системы с частым
чтением и относительно редкой записью. Чтобы определить, сколько подчиненных
систем нужно, следует опытным путем для наиболее типичных запросов установить
время чтения (max_reads
) и время записи
(max_writes
). Пример ниже покажет Вам довольно упрощенное
вычисление того, что Вы можете добиться с помощью репликации для нашей
предполагаемой системы.
Скажем, наша загрузка системы состоит на 10% из записи (90% чтение), и мы
определили, что max_reads
=1200-2*max_writes
, и
связь линейна. Допустим, что все машины имеют одинаковый канал связи. Значит,
мы имеем для каждой системы (N подчиненных и одна главная):
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 запросов на запись в секунду.
Если N=1, то наша система сможет обрабатывать уже до 184 запросов на запись в секунду.
Если N=8, дойдем до 400.
Если N=17, дойдем до 480.
В конечном счете, при приближении N к бесконечности (а нашего бюджета к минус бесконечности), мы сможем вплотную приблизиться к 600 запросам на запись в секунду, увеличивая производительность системы приблизительно в 5,5 раз. Однако, всего с 8 серверами удалось достичь роста почти в 4 раза.
Заметьте, что здесь не учитывалась пропускная способность сети и еще ряд важных факторов. Однако, ответ на следующие вопросы должен помочь решить, сколько машин для репликации нужно, и нужна ли она вообще:
Q: Как я могу использовать репликацию, чтобы обеспечить высокую/избыточную доступность?
A: Надо поставить главный и подчиненный (или несколько подчиненных) серверы и написать скрипт, который мониторит главную систему. В случае проблем с ней, он должен перевести нагрузку на другую машину. Некоторые мои предложения:
CHANGE MASTER TO
.
nsupdate
, чтобы динамически модифицировать Ваш DNS.
log-bin
, но без
log-slave-updates
. В этом случае подчиненный будет готов стать
главным, как только Вы выдаете команды STOP SLAVE
;
RESET MASTER
и CHANGE MASTER TO
на других
подчиненных системах. Это также поможет Вам захватить поддельные модификации,
которые могут случаться из-за ошибок в настройке подчиненных.Если все сделали правильно, но репликация не работает, сначала устраните фактор ошибки пользователя, проверяя следующее:
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, работает ли фактически главный сервер, достижим ли он с подчиненного и
почитать протокол ошибок.
SLAVE START
.
SET SQL_SLAVE_SKIP_COUNTER=1; SLAVE START;
, чтобы пропустить
запрос, который не использует auto_increment или last_insert_id, или задайте
SET SQL_SLAVE_SKIP_COUNTER=2; SLAVE START;
в противном случае.
Причина особой обработки запросов с auto_increment/last_insert_id в том, что
они берут два события в двоичном файле регистрации главной системы.
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 с настолько подробной информацией, насколько это возможно.
Все клиенты MySQL, которые связываются с сервером, используя библиотеку
mysqlclient
, применяет следующие системные переменные:
Имя | Описание |
MYSQL_UNIX_PORT | Сокет по умолчанию. Используется
для связи с localhost |
MYSQL_TCP_PORT | TCP/IP порт по умолчанию |
MYSQL_PWD | Пароль по умолчанию |
MYSQL_DEBUG | Опции для трассировки, если используется режим отладки |
TMPDIR | Каталог для временных файлов и таблиц |
Применение MYSQL_PWD
опасно. Подробности в разделе
"4.2.7 Соединение с сервером MySQL".
Клиент mysql использует файл, именованный в системной переменной
MYSQL_HISTFILE
, чтобы сохранить хронологию командной строки.
Значение по умолчанию для файла хронологии: $HOME/.mysql_history,
здесь $HOME
представляет собой значение системной переменной
HOME
. Подробности в разделе
"Приложение 2. Переменные окружения
".
Все программы MySQL имеют много различных параметров. Однако, каждая
программа MySQL обеспечивает опцию --help
, которую Вы можете
использовать, чтобы получить полное описание различных параметров программы.
Например, mysql --help
.
Вы можете отменять заданные по умолчанию параметры для всех стандартных программ пользователя с помощью файла опций. Подробности в разделе "4.1.2 Файл опций my.cnf".
Список ниже кратко описывает программы MySQL:
myisamchk
myisamchk
имеет много
функций, он описан в собственной главе. Подробности в разделе
"4 Администрирование СУБД
MySQL".
make_binary_distribution
support.mysql.com
для удобства других пользователей MySQL.
msql2mysql
mSQL
в
MySQL. Не обрабатывает все случаи, но дает хорошее начало при преобразовании.
mysqlaccess
mysqladmin
mysqladmin
может
также использоваться, чтобы узнавать версию, данные о процессах и информацию
состояния сервера. Подробности в разделе "
4.8.3 mysqladmin, администрирование сервера MySQL".
mysqlbug
mysqld
mysqldump
mysqlimport
LOAD DATA INFILE
. Подробности в разделе
"4.8.7 mysqlimport, импортирование данных из
текстовых файлов".
mysqlshow
mysql_install_db
replace
msql2mysql
, но имеет более
общую применимость. replace
меняет строки в файлах или на
стандартном вводе. Использует специальный алгоритм, чтобы сначала
соответствовать более длинным строкам. Может использоваться, чтобы менять
строки. Например, эта команда меняет a
и b
в файлах:
shell> replace a b b a -- file1 file2 ...
mysql
простая SQL оболочка (с возможностями GNU
readline
). Это поддерживает интерактивное и не интерактивное
использование. Когда используется в интерактивном режиме, результаты запроса
будут представлены в формате 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 database
. Напечатайте
инструкцию SQL, закончите ее `;', `\g' или
`\G' и нажмите RETURN/ENTER.
mysql
поддерживает следующие параметры:
-?, --help
-A, --no-auto-rehash
-B, --batch
--character-sets-dir=...
-C, --compress
-#, --debug[=...]
-D, --database=...
my.cnf
.
--default-character-set=...
-e, --execute=...
-E, --vertical
\G
.
-f, --force
-g, --no-named-commands
-G, --enable-named-commands
-i, --ignore-space
-h, --host=...
-H, --html
-L, --skip-line-numbers
--no-pager
--no-tee
-n, --unbuffered
-N, --skip-column-names
-O, --set-variable var=option
--help
.
-o, --one-database
--pager[=...]
PAGER
. Допустимые значения: less, more, cat [> filename],
etc. Подробности в интерактивной справке (\h). Эта опция не работает в
пакетном режиме. Pager работает только в UNIX.
-p[password], --password[=...]
-p
, Вы не
можете иметь пробелов между этой опцией и паролем.
-P --port=...
-q, --quick
-r, --raw
--batch
.
-s, --silent
-S --socket=...
-t --table
-T, --debug-info
--tee=...
-u, --user=#
-U, --safe-updates[=#], --i-am-a-dummy[=#]
UPDATE
и DELETE
, которые
используют ключи. Вы можете сбрасывать эту опцию, если Вы имеете ее в Вашем
файле my.cnf
, используя параметр --safe-updates=0
.
-v, --verbose
-V, --version
-w, --wait
Вы можете также устанавливать следующие переменные через -O
или --set-variable
:
Имя переменной | Значение по умолчанию | Описание |
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 commands: help (\h) Display this text. ? (\h) Synonym for `help'. clear (\c) Clear command. connect (\r) Reconnect to the server. Optional arguments are db and host. edit (\e) Edit command with $EDITOR. ego (\G) Send command to mysql server, display result vertically. exit (\q) Exit mysql. Same as quit. go (\g) Send command to mysql server. nopager (\n) Disable pager, print to stdout. notee (\t) Don't write into outfile. pager (\P) Set PAGER [to_pager]. Print the query results via PAGER. print (\p) Print current command. quit (\q) Quit mysql. rehash (\#) Rebuild completion hash. source (\.) Execute a SQL script file. Takes a file name as an argument. status (\s) Get status information from the server. tee (\T) Set outfile [to_outfile]. Append everything into given outfile. use (\u) Use another database. Takes database name as argument.
Внимание: pager работает только в UNIX.
Команда status
дает Вам некоторую информацию относительно
подключения и сервера, который Вы используете. Если Вы работаете в режиме
--safe-updates
, status
будет также печатать
значения для переменных mysql
, которые воздействуют
на Ваши запросы.
Полезная опция запуска для новичков (появилась в
MySQL Version 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
.
Подробности в разделе "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 Thimble> UTF-8 or Unicode? Otherwise I'll put this on my TODO list Thimble> and see what happens. Yes, please do that. Regards, Monty file: inbox-jani-1 hash: 190402944 1 row in set (0.09 sec)
tee
. Режим
tee
может быть начат с помощью опции --tee=...
или
из командной строки в интерактивном режиме с помощью команды
tee
. Все данные, отображаемые на экране, будут также добавляться
в заданный файл. Это может быть очень полезно для отладки. Режим может быть
заблокирован из командной строки командой notee
. Выполнение
tee
второй раз снова начинает регистрировать вывод. Без
параметра будет использоваться предыдущий файл. Обратите внимание, что
tee
сбрасывает результаты в файл после каждой команды прежде,
чем появляется командная строка.
--pager[=...]
. Без параметра клиент mysql
будет искать системную переменную PAGER и соответственно устанавливать свой
параметр pager
. Этот режим может быть запущен из интерактивной
командной строки командой pager
и заблокирован командой
nopager
. Команда факультативно берет параметр, и
pager
будет установлен в заданное им значение. Команда
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' или ';') и с вертикальным выводом (команды заканчиваются на '\G'). Иногда очень широкий набор результатов должен быстро читаться с экрана, с опцией -S и программой less Вы сможете просмотреть результаты внутри интерактивного less слева направо без строк, более длинных, чем Ваш экран. Это может сделать результат намного более читаемым. Вы можете переключать режим внутри интерактивного less с помощью '-S'. Подробности в описании на 'h'.
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
работает, даже
если Вы не имеете UNIX tee
.Утилита для выполнения административных операций. Синтаксис:
shell> mysqladmin [OPTIONS] command [command-option] command ...
Вы можете получить список параметров, которые Ваша версия
mysqladmin
поддерживает, выполняя mysqladmin
--help
.
Текущая версия mysqladmin
поддерживает следующие команды:
create databasename
drop databasename
extended-status
flush-hosts
flush-logs
flush-tables
flush-privileges
kill id,id,...
password
ping
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 | Число секунд, которые прошли с момента запуска сервера |
Threads | Число активных потоков (клиентов) |
Questions | Число запросов от клиентуры с тех пор, как
mysqld был запущен. |
Slow queries | Запросы, которые заняли больше, чем
long_query_time секунд. Подробности в разделе
"4.9.5 Медленный файл регистрации".
|
Opens | Сколько таблиц открылись в mysqld .
|
Flush tables | Сколько выполнено команд flush ... ,
refresh и reload .
|
Open tables | Число таблиц, которые открыты СЕЙЧАС. |
Memory in use | Память, распределенная непосредственно кодом
mysqld (доступно только, когда MySQL компилируется с опцией
--with-debug=full). |
Max memory used | Максимальная память, распределенная
непосредственно кодом mysqld (доступно только, когда MySQL
компилируется с опцией --with-debug=full). |
Если Вы делаете myslqadmin shutdown
на сокете (другими
словами, на компьютере, где запущен mysqld
),
mysqladmin
будет ждать, пока не будет удален MySQL
pid-file
, чтобы гарантировать, что сервер mysqld
был завершен правильно.
mysqlcheck
для поддержания таблиц и восстановленияНачиная с MySQL version 3.23.38, Вы можете использовать новый инструмент
для проверки и ремонта таблиц MyISAM
. Отличие от
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
mysqlcheck
имеет специальное свойство, сравнимое с другой
клиентурой: заданное по умолчанию поведение при проверке таблиц (-c) может
быть изменено переименованием. Так, если Вы хотите иметь инструмент для
ремонта таблиц по умолчанию, Вы должны только скопировать
mysqlcheck
под именем mysqlrepair
или создать
символическую связь mysqlrepair
.
Имена, которые Вы можете использовать, чтобы изменить заданное по
умолчанию поведение mysqlcheck
:
mysqlrepair: По умолчанию опция -r mysqlanalyze: По умолчанию опция -a mysqloptimize: По умолчанию опция -o
Параметры, доступные для mysqlcheck
, перечислены здесь,
пожалуйста, проверьте, что Ваша версия поддерживает вызов
mysqlcheck --help
.
-A, --all-databases
-1, --all-in-1
-a, --analyze
--auto-repair
-#, --debug=...
--character-sets-dir=...
-c, --check
-C, --check-only-changed
--compress
-?, --help
-B, --databases
--default-character-set=...
-F, --fast
-f, --force
-e, --extended
-h, --host=...
-m, --medium-check
-o, --optimize
-p, --password[=...]
-P, --port=...
-q, --quick
-r, --repair
-s, --silent
-S, --socket=...
--tables
-u, --user=#
-v, --verbose
-V, --version
Утилита позволяет сбросить в дамп одну или несколько баз данных для резервирования или транспортировки на другой сервер SQL (необязательно MySQL). Дамп будет содержать инструкции SQL, чтобы создать и заполнять таблицу данными.
Если Вы делаете копию на сервер, Вы должны рассмотреть использование
вместо этой утилиты mysqlhotcopy
. Подробности в разделе
"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
, mysqldump
загрузит целый набор результатов в память перед дампингом. Это будет,
вероятно, проблемой, если Вы обрабатываете большую базу данных.
Обратите внимание, что, если Вы используете новую копию программы
mysqldump
и собираетесь делать дамп, который будет читаться
очень старым сервером MySQL, Вы не должны использовать параметры
--opt
или -e
.
mysqldump
поддерживает следующие параметры:
--add-locks
LOCK TABLES
перед и UNLOCK TABLE
после
каждого дампа таблицы, чтобы получить быстрые вставки в MySQL.
--add-drop-table
drop table
перед каждой инстукцией создания.
-A, --all-databases
--databases
со всеми выбранными базами данных.
-a, --all
--allow-keywords
-c, --complete-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
.
-F, --flush-logs
-f, --force,
-h, --host=...
localhost
.
-l, --lock-tables
READ LOCAL
, чтобы позволить параллельные вставки в
случае таблиц MyISAM
.
-n, --no-create-db
-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]
-P port_num, --port=port_num
localhost
, там применяются Unix-сокеты.
-q, --quick
mysql_use_result()
.
-r, --result-file=...
-S /path/to/socket, --socket=/path/to/socket
localhost
.
Он является заданным по умолчанию компьютером.
--tables
-T, --tab=path-to-some-directory
table_name.sql
, который содержит команды SQL
CREATE, и файл table_name.txt
, который содержит данные для
каждой указанной таблицы. ОБРАТИТЕ ВНИМАНИЕ: Это работает
только, если mysqldump
выполнен на той же самой машине, что и
сервер mysqld
. Формат файла .txt
соответствует
опциям --fields-xxx
и --lines--xxx
.
-u user_name, --user=user_name
-O var=option, --set-variable var=option
-v, --verbose
-V, --version
-w, --where='where-condition'
"--where=user='jimf'" "-wuserid>1" "-wuserid<1"
-O net_buffer_length=#, where # < 16M
--extended-insert
или --opt
),
mysqldump
создаст строки длины до net_buffer_length
.
Если Вы увеличиваете эту переменную, Вы должны также гарантировать, что
переменная max_allowed_packet
в сервере MySQL больше, чем
net_buffer_length
.Наиболее нормальное использование mysqldump
: создание копий
целых баз данных. Подробности в разделе "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 database3...] > my_databases.sql
Если требуются все базы данных, можно использовать:
mysqldump --all-databases > all_databases.sql
mysqlhotcopy
представляет собой perl-скрипт, который
использует LOCK TABLES
, FLUSH TABLES
и
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
--keepold
--noindices
myisamchk -rq
.
--method=#
cp
или scp
).
-q, --quiet
--debug
-n, --dryrun
--regexp=#
--suffix=#
--checkpoint=#
--flushlog
--tmpdir=#
Вы можете использовать perldoc mysqlhotcopy
, чтобы получить
более полную документацию для mysqlhotcopy
.
mysqlhotcopy
читает группы [client]
и
[mysqlhotcopy]
из файлов опций.
Чтобы выполнить mysqlhotcopy
, Вы нуждаетесь в доступе к
резервному каталогу для записи, в привилегии SELECT
для таблиц,
которые Вы собираетесь копировать, и в привилегии MySQL Reload
,
чтобы выполнить команду FLUSH TABLES
.
mysqlimport
интерфейс командной строки к инструкции SQL
LOAD DATA INFILE
. Большинство параметров
mysqlimport
непосредственно соответствует тем же самым
параметрам LOAD DATA INFILE
.
mysqlimport
вызывается подобно этому:
shell> mysqlimport [options] database textfile1 [textfile2....]
Для каждого текстового файла, указанного в командной строке,
mysqlimport
отделяет любое расширение от имени файла и
использует результат, чтобы определить, в которую таблицу импортировать
содержание файла. Например, файлы с именами patient.txt,
patient.text и patient будут все вместе импортированы в
одну таблицу patient
.
mysqlimport
поддерживает следующие параметры:
-c, --columns=...
LOAD DATA
INFILE
, которая затем будет передана MySQL.
-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
.
-f, --force
--force
mysqlimport
прерывает работу, если нужная
таблица не существует.
--help
-h host_name, --host=host_name
localhost
.
-i, --ignore
--replace
.
-l, --lock-tables
-L, --local
localhost
(который является заданным по умолчанию компьютером).
-pyour_pass, --password[=your_pass]
mysqlimport
запросит
Вас относительно пароля.
-P port_num, --port=port_num
localhost
,
там применены сокеты Unix.
-r, --replace
--replace
и --ignore
контролируют
обработку управления параметров входных записей, которые дублируют
существующие записи на уникальных значениях ключа. Если Вы определяете
--replace
, новые строки заменят существующие, которые имеют то
же самое уникальное значение ключа. Если Вы определяете
--ignore
, они будут пропущены. Если Вы не определяете никакой
опции вообще, происходит ошибка, когда найдено двойное значение ключа, а
остальная часть текстового файла игнорируется.
-s, --silent
-S /path/to/socket, --socket=/path/to/socket
localhost
(является заданным по умолчанию компьютером).
-u user_name, --user=user_name
-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 | +------+---------------+
mysqlshow
может использоваться, чтобы быстро посмотреть,
какие базы данных существуют, их таблицы и столбцы этих таблиц.
Программой mysql
Вы можете получать ту же самую информацию
командой SHOW
. Подробности в разделе "
4.5.5 Синтаксис SHOW
".
mysqlshow
вызывается подобно этому:
shell> mysqlshow [OPTIONS] [database [table [column]]]
Обратите внимание, что в более новых версиях MySQL, Вы только видите те базы данных/таблицы/столбцы, для которых Вы имеете некоторые привилегии.
Если последний параметр содержит подстановочные знаки оболочки или SQL
(*
, ?
, %
или _
),
показывается только то, что согласовано групповым символом. Это может вызвать
некоторый беспорядок, когда Вы пробуете отображать столбцы для таблицы с
символом _
в имени, поскольку в этом случае
mysqlshow
показывает Вам имена, соответствующие образцу. Это
легко устранимо добавлением в конце командной строки символа %
(как отдельный параметр).
perror
может использоваться, чтобы печатать сообщения об
ошибках. perror
может вызываться подобно этому:
shell> perror [OPTIONS] [ERRORCODE [ERRORCODE...]] например: shell> perror 64 79 Error code 64: Machine is not on the network Error code 79: Can not access a needed shared library
perror
может использоваться, чтобы отобразить описание для
кода ошибки системы или драйвера таблицы MyISAM/ISAM. Сообщения об ошибках
обычно зависят от системы.
Клиент mysql
обычно используется в интерактивном режиме:
shell> mysql database
Однако, также возможно поместить Ваши команды SQL в файл и сообщить, чтобы
mysql
читал ввод из того файла. Чтобы сделать так, создайте
текстовый файл text_file, хранящий команды, которые Вы желаете
выполнить. Затем вызовите mysql
как показано ниже:
shell> mysql database < text_file
Вы можете также запустить Ваш текстовый файл с помощью инструкции
USE db_name
. В этом случае, не нужно определять имя базы данных
на командной строке:
shell> mysql < text_file
Прежде, чем Вы будете ставить исходники, проверьте, может быть Вас устроит двоичный дистрибутив. Дело в том, что авторы пакета сильно постарались, чтобы их двоичные дистрибутивы для разных платформ были сформированы с самыми лучшими возможными параметрами.
Вы нуждаетесь в следующих инструментальных средствах, чтобы сформировать и установить MySQL из исходников:
gunzip
для расжатия дистрибутива.
tar
, чтобы распаковать дистрибутив.
GNU tar
, как известно, работает. Sun tar
имеет
проблемы с именами файлов.
gcc
>= 2.95.2, egcs
>= 1.0.2 или egcs 2.91.66
, SGI C++ и SunPro C++ это
некоторые из компиляторов, которые, как известно, работают.
libg++
не требуется при использовании gcc
.
gcc
2.7.x имеет ошибку, которая делает невозможным компиляцию
некоторых совершенно нормальных файлов C++, типа sql/sql_base.cc.
Если Вы имеете только gcc
2.7.x, Вы должны обновить компилятор,
чтобы быть способными компилировать MySQL. gcc
2.8.1, как
известно, имеет проблемы на некоторых платформах, так что этого нужно
избежать, если там существует новый компилятор для этой платформы.
gcc
>= 2.95.2 рекомендуется при компиляции MySQL 3.23.x.
make
. GNU make
всегда
рекомендуется и иногда требуется. Если Вы имеете проблемы, я рекомендую
попробовать GNU make
3.75 или более новую.Если Вы используете недавнюю версию gcc, проверьте
использование опции -fno-exceptions
. ОЧЕНЬ
ВАЖНО, чтобы Вы использовали ее. Иначе Вы можете компилировать
двоичный код, который беспорядочно терпит крах. Я также рекомендую, чтобы Вы
использовали -felide-contructors
и -fno-rtti
наряду
с -fno-exceptions
. Если сомневаетесь, сделайте следующее:
CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static
На большинстве систем это даст Вам быстрый и устойчивый двоичный код.
Если Вы сталкиваетесь с проблемами, ПОЖАЛУЙСТА ВСЕГДА ИСПОЛЬЗУЙТЕ
mysqlbug
при регистрации вопросов в
mysql@lists.mysql.com. Даже если
проблема не является ошибкой, mysqlbug
собирает информацию
системы, которая поможет другим решить Вашу проблему. Не используя
mysqlbug
,Вы уменьшаете вероятность получения решения для Вашей
проблемы! Вы найдете mysqlbug
в каталоге scripts после
распаковки дистрибутива. Подробности в разделе
"1.4.1 Как сообщать об ошибках и проблемах
".
Базисные команды, которые Вы должны выполнить, чтобы установить исходники MySQL, выглядят так:
shell> groupadd mysql shell> useradd -g mysql mysql shell> gunzip < mysql-VERSION.tar.gz | tar -xvf - shell> cd mysql-VERSION shell> ./configure --prefix=/usr/local/mysql shell> make shell> make install shell> scripts/mysql_install_db shell> chown -R root /usr/local/mysql shell> chown -R mysql /usr/local/mysql/var shell> chgrp -R mysql /usr/local/mysql shell> cp support-files/my-medium.cnf /etc/my.cnf shell> /usr/local/mysql/bin/safe_mysqld --user=mysql &
Если Вы хотите иметь поддержку для таблиц InnoDB, Вы должны
отредактировать файл /etc/my.cnf
и удалить символ #
перед параметрами, которые начинаются с innodb_...
. Подробности
в разделе "4.1.2 Файл опций my.cnf" и в
разделе "7.6.2 Параметры запуска InnoDB
".
Вы можете добавлять новых пользователей, используя скрипт
bin/mysql_setpermission
, если Вы устанавливаете Perl-модули
DBI
и Msql-Mysql-modules
.
Чтобы устанавливать исходники, выполните приведенные ниже действия, а затем перейдите к разделу "2.4 Послеустановочная настройка и тестирование" для инициализации пост-установки и тестирования:
mysqld
:
shell> groupadd mysql shell> useradd -g mysql mysqlЭти команды добавляют группу
mysql
и пользователя
mysql
. Синтаксис для useradd
и
groupadd
может немного отличаться в различных версиях Unix. Они
также могут быть названы adduser
и addgroup
.
shell> gunzip < /path/to/mysql-VERSION.tar.gz | tar xvf -Эта команда создает каталог, именованный mysql-VERSION. Дистрибутивы представляют собой сжатые архивы с именами вроде mysql-VERSION.tar.gz , где VERSION определяет версию дистрибутива.
shell> cd mysql-VERSIONОбратите внимание, что в настоящее время Вы должны конфигурировать и формировать MySQL из этого каталога. Вы не можете формировать его, находясь в каком-то ином каталоге.
shell> ./configure --prefix=/usr/local/mysql shell> makeКогда Вы выполняете
configure
, Вы можете определять некоторые
дополнительные параметры. Выполните ./configure --help
, чтобы
получить перечень опций. В разделе "
2.3.3 Типичные опции configure
" обсуждаются некоторые из
наиболее полезных параметров. Если происходит сбой скрипта
configure
, и Вы собираетесь посылать сообщение об этом на
mysql@lists.mysql.com, чтобы
попросить о помощи, пожалуйста, включите в письмо строки из файла
config.log, которые, как Вы думаете, могут помочь решить проблему.
Также включите последнюю тройку строк из вывода configure
, если
configure
прерывается. Регистрируйте отчет ошибки, используя
скрипт mysqlbug
. Подробности в разделе
"1.4.1 Как сообщать об ошибках и проблемах
". Если компиляция не проходит нормально, обратитесь к разделу
"2.3.5 Проблемы компиляции".
shell> make installСкорее всего, Вы должны выполнить эту команду как
root
.
shell> scripts/mysql_install_dbОбратите внимание, что версии MySQL старше, чем Version 3.22.10, запускали сервер MySQL, когда Вы выполняли скрипт
mysql_install_db
. Это
больше не так!
root
и задайте в
качестве владельца каталога данных пользователя, от имени которого будет
работать сервер mysqld
:
shell> chown -R root /usr/local/mysql shell> chown -R mysql /usr/local/mysql/var shell> chgrp -R mysql /usr/local/mysqlПервая команда изменяет атрибут владельца файлов (
owner
) на
пользователя root
, второй изменяет атрибут владельца каталога
данных на пользователя mysql
, а третий меняет атрибут группы
владельца каталога данных (group
) на группу mysql
.
support-files/mysql.server
в
место, где Ваша система имеет файлы запуска. Большее количество информации
может быть найдено непосредственно в скрипте
support-files/mysql.server
и в разделе
"2.4.3 Автозапуск и завершение MySQL
".После того, как все было установлено, Вы должны инициализировать и проверить Ваш дистрибутив:
shell> /usr/local/mysql/bin/safe_mysqld --user=mysql &
Если эта команда немедленно валится с диагностикой mysqld daemon
ended
, Вы можете найти некоторую информацию в файле
mysql-data-directory/'hostname'.err. Вероятная причина в том, что Вы
уже имеете запущенный сервер mysqld
. Подробности в разделе
"4.1.4 Запуск нескольких серверов
MySQL на одной машине".
Иногда заплаты появляются в списке рассылки или помещаются в области заплат сайта MySQL ( http://www.mysql.com/Downloads/Patches).
Чтобы применить заплату из списка рассылки, сохраните сообщение, в котором пришла заплата, перейдите в верхний каталог Вашего дерева исходников MySQL и введите оттуда команды:
shell> patch -p1 < patch-file-name shell> rm config.cache shell> make clean
Заплаты с FTP-сайта распространяются как простые текстовые файлы или как
файлы, сжатые gzip
. Примените простую заплату как показано выше
для заплат из списка рассылки. Чтобы применить сжатую заплату, из верхнего
каталога Вашего дерева исходников MySQL надо ввести следующее:
shell> gunzip < patch-file-name.gz | patch -p1 shell> rm config.cache shell> make clean
После применения патча, выполните команды по настройке, компиляции и
установке сервера. После make install
перезапустите сервер.
Вы должны завершить работу сервера перед выполнением make
install
. Для этого используйте команду mysqladmin
shutdown
. Некоторые системы не позволяют Вам устанавливать новую
версию программы, если она заменяет собой ту версию, которая в
настоящее время выполняется.
configure
Скрипт configure
дает Вам хороший контроль над тем, как Вы
конфигурируете свой дистрибутив MySQL. Чтобы получить список опций,
configure
, выполните команду:
shell> ./configure --help
Некоторые из наиболее часто используемых параметров configure
подробно описаны ниже:
--without-server
:
shell> ./configure --without-serverЕсли Вы не имеете компилятора C++,
mysql
не скомпилируется (есть
одна программа-клиент, которая требует наличия C++). В этом случае Вы можете
удалить код в выборе конфигурации, который проверяет наличие компилятора C++,
и снова выполнить ./configure
с опцией
--without-server
. Шаг компиляции все еще будет пробовать
формировать mysql
, но Вы можете игнорировать любые
предупреждения относительно mysql.cc. Если make
останавливается, попытайтесь применить make -k
, чтобы сообщить,
чтобы процесс продолжался, даже если происходят ошибки.
configure
в следующем виде:
shell> ./configure --prefix=/usr/local/mysql shell> ./configure --prefix=/usr/local \ --localstatedir=/usr/local/mysql/dataПервая команда изменяет префикс установки так, чтобы все было установлено под /usr/local/mysql, а не в /usr/local. Вторая команда сохраняет заданный по умолчанию префикс установки, но отменяет заданное по умолчанию расположение для каталогов баз данных (обычно /usr/local/var) и изменяет его на
/usr/local/mysql/data
.
configure
:
shell> ./configure \ --with-unix-socket-path=/usr/local/mysql/tmp/mysql.sockОбратите внимание, что данный файл должен быть абсолютным именем! Вы можете также позже изменять расположение mysql.sock, используя файлы опций MySQL. Подробности в разделе "8.4.5 Как защищать или менять файл сокета MySQL /tmp/mysql.sock".
configure
примерно так:
shell> ./configure --with-client-ldflags=-all-static \ --with-mysqld-ldflags=-all-static
gcc
и не имеете установленных библиотек
libg++
или libstdc++
, Вы можете сообщить, чтобы
configure
использовал gcc
как Ваш компилятор C++:
shell> CC=gcc CXX=gcc ./configureКогда Вы используете
gcc
как Ваш компилятор C++, он не будет
пытаться компоновать с libg++
или libstdc++
.
Имеются некоторые общие системные переменные, которые надо установить в
зависимости от того компилятора, который Вы используете:
gcc 2.7.2.1 | CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors" |
egcs 1.0.3a | CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti" |
gcc 2.95.2 | CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro -felide-constructors -fno-exceptions -fno-rtti" |
pgcc 2.90.29 или более новый | CFLAGS="-O3 -mpentiumpro -mstack-align-double" CXX=gcc CXXFLAGS="-O3 -mpentiumpro -mstack-align-double -felide-constructors -fno-exceptions -fno-rtti" |
--prefix=/usr/local/mysql --enable-assembler \ --with-mysqld-ldflags=-all-staticПолная строка выбора конфигурации была бы, другими словами, чем-то вроде следующего для всех недавних версий gcc:
CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro -felide-constructors \ -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler \ --with-mysqld-ldflags=-all-static
Все двоичные дистрибутивы с сайта MySQL ( http://www.mysql.com) компилируются с полной оптимизацией и должны быть пригодны для большинства пользователей.Подробности в разделе "2.2.6 Двоичные версии MySQL, скомпилированные MySQL AB". Имеются некоторые вещи, которые Вы можете подправить, чтобы сделать версию более быстрой, но это только для продвинутых пользователей. Подробности в разделе "5.5.3 Как компиляция и компоновка воздействует на быстродействие MySQL".
Если процесс построения кода валится с ошибкой создания разделяемой
библиотеки libmysqlclient.so.# (`#' представляет собой
код версии), Вы можете обойти эту проблему, задавая опцию
--disable-shared
в строке для вызова configure
. В
этом случае configure
не будет формировать общедоступную
библиотеку libmysqlclient.so.#
.
DEFAULT
для не пустых столбцов (то есть столбцов, которым не
позволяют иметь значение NULL
). Это заставляет инструкции
INSERT
генерировать ошибку, если Вы явно не определяете значения
для всех столбцов, которые требуют значения не-NULL
. Чтобы
подавить использование значений по умолчанию, выполните выбор
конфигурации подобно этому:
shell> CXXFLAGS=-DDONT_USE_DEFAULT_FIELDS ./configure
--with-charset
:
shell> ./configure --with-charset=CHARSET
CHARSET
может быть одним из значений big5
,
cp1251
, cp1257
, czech
,
danish
, dec8
, dos
,
euc_kr
, gb2312
, gbk
,
german1
, hebrew
, hp8
,
hungarian
, koi8_ru
, koi8_ukr
,
latin1
, latin2
, sjis
,
swe7
, tis620
, ujis
, usa7
или win1251ukr
. Подробности в разделе
"4.6.1 Набор символов, используемый
для данных и сортировки". Если Вы хотите преобразовывать символы между
клиентом и сервером, Вы должны изучить команду SET OPTION CHARACTER
SET
. Подробности в разделе "5.5.6
Синтаксис SET
".
Предупреждение: Если Вы изменяете наборы символов, создав
любые таблицы, Вы должны выполнить на каждой таблице
myisamchk -r -q
. Иначе Ваши индексы могут сортироваться
неправильно. Это может случиться, если Вы устанавливаете MySQL, создаете
некоторые таблицы, затем реконфигурируете MySQL, чтобы использовать иной
набор символов, и повторно устанавливаете его. С опцией
--with-extra-charset=LIST
Вы можете определять, которые
дополнительные наборы символов должны быть скомпилированы в код сервера.
Здесь LIST
является или списком набора символов, разделяемых
пробелами с параметром complex
, чтобы включить все символы,
которые не могут быть динамически загружены, или all
, чтобы
включить все наборы символов.
--with-debug
:
shell> ./configure --with-debugЭто заставляет включить безопасный распределитель памяти, что может находить некоторые ошибки, и обеспечивает вывод относительно того, что происходит. Подробности в разделе " 6.1 Отладка сервера MySQL".
--enable-thread-safe-client
.
Это создаст библиотеку libmysqlclient_r
, с которой Вы должны
скомпоновать свои прикладные программы.
ПРЕДОСТЕРЕЖЕНИЕ: Вы должны читать этот раздел только, если Вы заинтересованы в помощи авторам и отладке кода. Если Вы только хотите получить MySQL и использовать его на своей системе, Вы должны использовать стандартный дистрибутив (двоичный или с исходниками).
Чтобы получить самое современное дерево источников разработок, используйте эти команды:
shell> bk clone bk://work.mysql.com:7000 mysql
Для получения кода версии 4.0, используйте такую команду:
shell> bk clone bk://work.mysql.com:7001 mysql-4.0
Начальная загрузка исходного дерева может требовать времени в зависимости от быстродействия Вашего подключения, будьте терпеливы.
autoconf
, automake
,
libtool
и макропроцессоре m4
, чтобы выполнить
следующий набор команд. Если Вы получаете некоторую странную ошибку в течение
этой стадии, проверьте, что Вы действительно имеете установленный
libtool
!
shell> cd mysql shell> bk -r edit shell> aclocal; autoheader; autoconf; automake; shell> ./configure # Add your favorite options here shell> make
Совокупность стандартных скриптов выбора конфигурации размещена в подкаталоге BUILD. В самом простом случае Вы можете использовать BUILD/compile-pentium-debug. Чтобы компилировать на различной архитектуре, измените скрипт, убрав из него параметры, которые являются специфическими для Pentium.
make install
. Будьте
внимательным с этим на промышленной машине: команда может записывать поверх
Вашей работающей установки. Если Вы имеете другую установку MySQL, задайте
для ./configure
другие значения для параметров
prefix
, tcp-port
и unix-socket-path
.
make
, но дистрибутив не
компилируется, пожалуйста, сообщите об этом на
bugs@lists.mysql.com. Если Вы
установили последние версии требуемых инструментальных средств GNU, и они
разрушаются при попытке обработать наши файлы конфигурации, пожалуйста,
сообщите об этом. Однако, если Вы выполняете aclocal
и получаете
ошибку command not found
или подобную проблему, не сообщайте об
этом. Вместо этого, удостоверьтесь, что все необходимые инструментальные
средства установлены, и что Ваша переменная PATH
установлена
правильно, так что Ваша оболочка может находить их.
bk clone
получила
исходное дерево, Вы должны периодически выполнять bk pull
,
чтобы получать модификации.
bk sccstool
. Если Вы видите некоторый забавный diffs
или код, относительно которого есть вопросы, без колебаний посылайте запрос
на internals@lists.mysql.com.
Также, если Вы думаете, что Вы имеете лучшую идею относительно того, как
что-то сделать, посылайте e-mail на тот же самый адрес с патчем. bk
diffs
произведет заплату для Вас после того, как Вы сделали изменения
для исходника. Если Вы не имеете времени на кодирование Вашей идеи, только
пошлите ее описание.
bk helptool
.Все программы MySQL компилируются чисто, без предупреждений, на Solaris с
применением gcc
. На других системах предупреждения могут
происходить из-за различий в системе и включаемых файлов. В разделе
"2.3.6 Замечания по MIT-pthreads" есть
подробности для предупреждений, которые могут происходить при использовании
MIT-pthreads. Для других проблем проверьте список ниже.
Решение для многих проблем включает повторное конфигурирование. Если Вы должны реконфигурировать пакет, примите во внимание следующее:
configure
выполнен после того, как он уже был
выполнен, это может использовать информацию, которая была собрана в течение
предыдущего обращения. Эта информация сохранена в файле
config.cache. Когда configure
запускается, он ищет этот
файл и читает его содержание, если файл существует, при условии, что
информация все еще правильна. При реконфигурировании это не так.
configure
, Вы должны снова
выполнить make
, чтобы перетранслировать пакет. Однако, Вы можете
удалять старые объектные файлы потому, что они компилировались, используя
иные параметры конфигурации.Чтобы избавиться от старой информации о конфигурации или объектных файлов,
выполните эти команды перед повторным запуском configure
:
shell> rm config.cache shell> make clean
Альтернативно, Вы можете выполнять make distclean
.
Список ниже описывает некоторые из проблем при компиляции MySQL, которые были найдены наиболее часто:
Internal compiler error: program cc1plus got fatal signal 11 или Out of virtual memory или Virtual memory exhaustedПроблема состоит в том, что
gcc
требует огромные объемы памяти
для компиляции sql_yacc.cc со встроенными функциями. Попробуйте
вызвать configure
с опцией --with-low-memory
:
shell> ./configure --with-low-memoryЭта опция добавляет
-fno-inline
, если Вы используете
gcc
, или -O0
, если Вы используете что-то иное. Вы
должны опробовать опцию --with-low-memory
даже, если Вы имеете
так много памяти, что не ожидаете ее исчерпания. Эта проблема наблюдалась
даже на системах с громадными аппаратными конфигурациями, и опция
--with-low-memory
обычно ее решает.
configure
указывает c++
как имя
компилятора и GNU c++
компонуется с -lg++
. Если Вы
используете gcc
, такое поведение может вызать проблемы в течение
конфигурации, типа этой:
configure: error: installation or configuration problem: C++ compiler cannot create executables.Вы можете также наблюдать, что проблемы в течение трансляции касаются
g++
, libg++
или же libstdc++
.
Одна из причин этих проблем в том, что Вы не можете иметь g++
,
или Вы можете иметь g++
, но не libg++
или
libstdc++
. Изучите файл config.log. Он должен содержать
точную причину того, почему Ваш компилятор c++ не работал! Чтобы обойти эти
проблемы, Вы можете использовать gcc
как компилятор C++.
Попробуйте устанавливать системную переменную CXX
в значение
"gcc -O3"
. Например, так:
shell> CXX="gcc -O3" ./configureЭто работает потому, что
gcc
компилирует исходники C++ также,
как g++
, но по умолчанию не выполняет компоновку с библиотеками
libg++
или libstdc++
. Другой способ решить эти
проблемы, конечно, состоит в том, чтобы установить g++
,
libg++
и libstdc++
.
make
до GNU make
:
making all in mit-pthreads make: Fatal error in reader: Makefile, line 18: Badly formed macro assignment или make: file `Makefile' line 18: Must be a separator (: или pthread.h: No such file or directorySolaris и FreeBSD, как известно, имеют ненадежные программы
make
. GNU make
Version 3.75 работает.
CFLAGS
и CXXFLAGS
. Вы можете также определять имена
трансляторов, используя переменные
CC
и CXX
. Например:
shell> CC=gcc shell> CFLAGS=-O3 shell> CXX=gcc shell> CXXFLAGS=-O3 shell> export CC CFLAGS CXX CXXFLAGSПодробности в разделе "2.2.6 Двоичные версии MySQL, скомпилированные MySQL AB", там есть список определений, которые были найдены полезными на различных системах.
gcc
:
client/libmysql.c:273: parse error before `__attribute__'
gcc
2.8.1, как известно, работает, но рекомендуется использовать
вместо него gcc
2.95.2 или egcs
1.0.3a.
mysqld
, стало быть скрипт configure
правильно не
обнаруживали тип последнего параметра для вызовов accept()
,
getsockname()
или getpeername()
:
cxx: Error: mysqld.cc, line 645: In this statement, the referenced type of the pointer value "&length" is "unsigned long", which is not compatible with "int". new_sock = accept(sock, (struct sockaddr *)&cAddr, &length);
Чтобы исправить это, отредактируйте файл config.h (который
сгенерирован configure
). Ищите эти строки:
/* Define as the base type of the last arg to accept */ #define SOCKET_SIZE_TYPE XXXСмените
XXX
на size_t
или int
, в
зависимости от Вашей операционной системы. Обратите внимание, что Вы должны
делать это, каждый раз, когда Вы выполняете configure
, поскольку
configure
всегда пересоздает файл config.h.
"sql_yacc.yy", line xxx fatal: default action causes potential...Это знак того, что Ваша версия
yacc
несовершенная. Вы, вероятно,
должны установить bison
(GNU-версия yacc
) и
использовать его вместо своей версии.
mysqld
или MySQL-клиента, запустите
configure
с опцией --with-debug
, это
перетранслирует и скомпонует Вашу клиентуру с новой библиотекой
пользователей. Подробности в разделе "
6.2 Отладка клиентов MySQL".Этот раздел описывает некоторые из проблем в использовании MIT-pthreads.
Обратите внимание, что в Linux Вы не должны использовать MIT-pthreads, а установить вместо него LinuxThreads! Подробности в разделе "2.6.1 Замечания по Linux (все версии Linux)".
Если Ваша система не обеспечивает местную поддержку потоков, Вы должны формировать MySQL с применением пакета MIT-pthreads. Это включает старые системы FreeBSD, SunOS 4.x, Solaris 2.4 и ранее и некоторые другие. Подробности в разделе "2.2.2 Операционные системы, поддерживаемые MySQL".
configure
с опцией
--with-mit-threads
:
shell> ./configure --with-mit-threads
Формирование дистрибутива не в каталоге исходников не поддержано при использовании MIT-pthreads, поскольку разработчикам MySQL лень править код.
--without-server
, чтобы формировать только код пользователя,
клиентура не будет знать, используется или нет MIT-pthreads, и по умолчанию
использует Unix-подключения через сокеты. Поскольку Unix-сокеты не работают
под MIT-pthreads, это означает, что Вы будете должны использовать параметры
-h
или --host
, когда Вы выполняете клиентов.
--use-locking
.
bind()
не может связаться с сокетом
без любых сообщений об ошибках (по крайней мере, на Solaris). Результат то,
что все подключения к серверу терпят неудачу. Например:
shell> mysqladmin version mysqladmin: connect to server at '' failed; error: 'Can't connect to mysql server on localhost (146)'Решение для этого состоит в том, чтобы перезапустить
mysqld
.
sleep()
не прерывается
сигналом SIGINT
(break). Это важно только, когда Вы выполняете
mysqladmin --sleep
. Вы должны ждать завершения обращения
sleep()
. Только после этого процесс наконец завершится.
ld: warning: symbol `_iob' has differing sizes: (file /my/local/pthreads/lib/libpthread.a(findfp.o) value=0x4; file /usr/lib/libc.so value=0x140); /my/local/pthreads/lib/libpthread.a(findfp.o) definition taken ld: warning: symbol `__iob' has differing sizes: (file /my/local/pthreads/lib/libpthread.a(findfp.o) value=0x4; file /usr/lib/libc.so value=0x140); /my/local/pthreads/lib/libpthread.a(findfp.o) definition taken
implicit declaration of function `int strtoll(...)' implicit declaration of function `int strtoul(...)'
Начиная с MySQL Version 3.23.6, Вы можете выбирать между тремя базисными
форматами таблиц (ISAM
, HEAP
и MyISAM
.
Более новый MySQL может поддерживать дополнительные типы таблиц
(BDB
или InnoDB
) в зависимости от того, как
Вы его компилируете. Когда Вы создаете новую таблицу, Вы можете сообщать
MySQL, какой именно тип таблиц он должен использовать для таблицы. MySQL
будет всегда создавать файл .frm
, чтобы сохранить определения
столбцов и таблицы. В зависимости от типа таблицы, индекс и данные будут
сохранены в других файлах.
Обратите внимание, что, чтобы использовать таблицы системы
InnoDB
, Вы должны использовать по крайней мере опцию запуска
innodb_data_file_path
. Подробности в разделе
"7.6.2 Опции запуска InnoDB".
Заданный по умолчанию тип таблицы в MySQL: MyISAM
. Если Вы
пробуете использовать тип таблицы, который не откомпилирован или
активизирован, MySQL взамен создаст таблицу системы MyISAM
. Это
очень полезное свойство, когда Вы хотите копировать таблицы между различными
серверами SQL, которые поддерживают различные типы таблиц (подобно
копированию на подчиненный сервер, который оптимизирован для быстродействия и
не имеет таблиц с поддержкой транзакций. Это автоматическое изменение таблицы
может сильно запутать новых пользователей.
Вы можете преобразовывать таблицы между различными типами
инструкцией ALTER TABLE
.
Обратите внимание, что MySQL поддерживает два различных вида таблиц.
Транзакционно-безопасные таблицы (BDB
и InnoDB
) и
транзакционно-небезопасные таблицы (HEAP
, ISAM
,
MERGE
и MyISAM
).
Преимущества транзакционно-безопасных таблиц (transaction-safe tables, TST):
ROLLBACK
, чтобы игнорировать внесенные
изменения (если Вы не работаете в режиме auto commit).
Преимущества транзакционно-небезопасных таблиц (transaction-safe tables, NTST):
Вы можете объединять TST и NTST таблицы в одних и тех же инструкциях.
Таблицы InnoDB включены в исходники MySQL, начиная с версии 3.23.34a, и активизированы в двоичной версии MySQL-max.
Если Вы загрузили двоичную версию MySQL, которая включает поддержку для InnoDB (mysqld-max), просто поставьте ее и все.
Чтобы откомпилировать MySQL с поддержкой InnoDB, загрузите MySQL-3.23.37
или более новую версию, и сконфигурируйте MySQL с опцией
--with-innodb
:
cd /path/to/source/of/mysql-3.23.37 ./configure --with-innodb
Чтобы запустить InnoDB, Вы должны определить, где должны быть сохранены
данные для таблиц InnoDB, определяя опцию innodb_data_file_path
в командной строке или в файле опций MySQL. Подробности в разделе
"7.6.2 Опции запуска InnoDB". Если Вы
сконфигурировали MySQL для InnoDB, но не определили вышеупомянутую опцию,
mysqld
при старте сообщит:
Can't initialize InnoDB as 'innodb_data_file_path' is not set
InnoDB обеспечивает MySQL транзакционно-безопасным драйвером таблицы с
поддержкой обработки нескольких запросов сразу, обратной перемотки и
возможности восстановления после аварийного отказа. InnoDB обеспечивает
блокировку на уровне строки и также обеспечивает Oracle-стиль
непротиворечивым чтением без блокировки в операторах SELECT
,
который увеличивает параллелизм транзакции.
Формат InnoDB был разработан для максимальной эффективности при обработке больших объемов данных.
Вы можете найти последнюю информацию относительно InnoDB на http://www.innodb.com. Наиболее современная версия руководства по InnoDB помещается там, и Вы можете также купить коммерческую поддержку для таблиц InnoDB.
Технически InnoDB представляет собой базу данных, помещенную под MySQL.
InnoDB имеет собственное буферное объединение для кэширования данных и
индексов в основной памяти. InnoDB сохраняет таблицы и индексы в пространстве
таблицы, которое может состоять из нескольких файлов. Это отличается,
например, от таблиц MyISAM
, где каждая таблица сохранена
как отдельный файл.
InnoDB распространяется под GNU GPL License Version 2 (June 1991). В дистрибутиве исходных текстов MySQL, InnoDB появляется как подкаталог.
Начиная с MySQL-3.23.37, префикс параметров изменен с
innobase_...
на innodb_...
.
Чтобы использовать InnoDB, Вы ДОЛЖНЫ определить параметры
конфигурации MySQL в секции [mysqld]
файла конфигурации
my.cnf. Подробности в разделе "
4.1.2 Файл опций my.cnf".
Единственный требуемый параметр, чтобы использовать InnoDB:
innodb_data_file_path
, но Вы должны установить и другие, если
хотите получить лучшую эффективность.
Предположим, что Вы имеете машину под Windows NT с 128 MB RAM и одним жестким диском на 10 GB. Ниже приведен пример возможных параметров конфигурации в my.cnf для InnoDB:
innodb_data_file_path = ibdata1:2000M;ibdata2:2000M innodb_data_home_dir = c:\ibdata set-variable = innodb_mirrored_log_groups=1 innodb_log_group_home_dir = c:\iblogs set-variable = innodb_log_files_in_group=3 set-variable = innodb_log_file_size=30M set-variable = innodb_log_buffer_size=8M innodb_flush_log_at_trx_commit=1 innodb_log_arch_dir = c:\iblogs innodb_log_archive=0 set-variable = innodb_buffer_pool_size=80M set-variable = innodb_additional_mem_pool_size=10M set-variable = innodb_file_io_threads=4 set-variable = innodb_lock_wait_timeout=50
Обратите внимание, что файлы данных должны быть < 4G и < 2G на некоторых файловых системах! Полный размер файлов данных должен быть >=10 MB. InnoDB не создает каталоги, Вы должны создать их непосредственно.
Предположим, что Вы имеете Linux-машину с 512 MB RAM и тремя жесткими дисками по 20 GB (смонтированы как каталоги /, /dr2 и /dr3). Ниже приведен пример возможных параметров конфигурации в my.cnf для InnoDB:
innodb_data_file_path = ibdata/ibdata1:2000M;dr2/ibdata/ibdata2:2000M innodb_data_home_dir = / set-variable = innodb_mirrored_log_groups=1 innodb_log_group_home_dir = /dr3 set-variable = innodb_log_files_in_group=3 set-variable = innodb_log_file_size=50M set-variable = innodb_log_buffer_size=8M innodb_flush_log_at_trx_commit=1 innodb_log_arch_dir = /dr3/iblogs innodb_log_archive=0 set-variable = innodb_buffer_pool_size=400M set-variable = innodb_additional_mem_pool_size=20M set-variable = innodb_file_io_threads=4 set-variable = innodb_lock_wait_timeout=50
Обратите внимание, что мы поместили два файла данных на различные диски.
Причина для имени innodb_data_file_path
в том, что Вы можете
также определять и пути к Вашим файлам данных, а
innodb_data_home_dir
будет добавлен перед Вашими путями к файлу
данных, добавляя возможную наклонную черту вправо или наклонную черту влево
по мере надобности. InnoDB заполнит пространство таблицы сформированными
файлами данных из нижней части. В некоторых случаях это улучшит эффективность
базы данных, если все данные не помещены на тот же самый физический диск.
Помещение журналов на другом диске часто очень полезно для эффективности.
Значения параметров конфигурации следующие:
innodb_data_home_dir | Общая часть пути каталога для всех файлов данных InnoDB. |
innodb_data_file_path | Пути к индивидуальным файлам данных и их размеры. Полный путь каталога к каждому файлу данных строится, связывая innodb_data_home_dir с путями, определенными здесь. Размеры файлов определены в мегабайтах, следовательно, M после спецификации размера выше подразумевается. Не устанавливайте размер файла больше, чем 4000M, а на большинстве операционных систем не больше, чем 2000M. InnoDB также понимает сокращение 'G', 1G означает 1024M. Сумма размеров файлов должна быть по крайней мере 10 MB. |
innodb_mirrored_log_groups | Число идентичных копий файла регистрации групп, которые мы храним для базы данных. В настоящее время это должно быть установлено в 1. |
innodb_log_group_home_dir | Путь к журналам InnoDB. |
innodb_log_files_in_group | Число журналов в группе файла регистрации.. InnoDB обеспечивает ротацию журналов. Рекомендуется использовать значение 3. |
innodb_log_file_size | Размер каждого журнала в файле регистрации групп в мегабайтах. Разумные значения располагаются от 1M до размера буферного пула, определенного ниже. Чем больше значение, тем меньше будет число контрольных точек сброса данных в буферном пуле, что уменьшит медленный дисковый ввод-вывод. Но большие журналы также означают, что восстановление будет медленнее в случае аварийного отказа. Ограничение размера файла такое же, что и у файла данных. |
innodb_log_buffer_size | Размер буфера, который InnoDB использует, чтобы писать файлы регистрации на диск. Разумные значения располагаются от 1M до половины объединенного размера журналов. Большой буфер файлов регистрации позволяет большим транзакциям выполняться без необходимости писать файл регистрации на диск, пока транзакция не закончится. Таким образом, если Вы имеете большие транзакции, увеличение буфера файла регистрации уменьшит медленный дисковый ввод-вывод. |
innodb_flush_log_at_trx_commit | Обычно это установлено в 1, означая, что при выполнении транзакции файл регистрации будет сброшен на диск, модификации, сделанные транзакцией, станут постоянными, что позволит им благополучно пережить аварийный отказ базы данных. Если Вы желаете отменить это ограничение, и Вы управляете маленькими транзакциями, Вы можете устанавливать это значение в 0, чтобы уменьшить медленный дисковый ввод-вывод файлов регистрации, но это опасно. |
innodb_log_arch_dir | Каталог, где будут
находиться архивы журналов протоколирования, если Вы использовали
архивирование файла регистрации. Значение этого параметра должно в настоящее
время быть установлено так же, как и innodb_log_group_home_dir .
|
innodb_log_archive | Это значение должно быть в настоящее время установлено в 0. Поскольку восстановление из копии выполняется MySQL с использованием собственных журналов, в настоящее время не имеется никакой потребности архивировать журналы InnoDB. |
innodb_buffer_pool_size | Размер памяти для буфера InnoDB, используемого, чтобы кэшировать данные и индексы таблиц. Увеличение буфера снижает медленные дисковые операции, необходимые, чтобы обратиться к данным в таблицах. На специализированном сервере базы данных Вы можете поднять этот параметр до 90% от физического размера памяти компьютера. Но не увлекайтесь этим, чтобы не вызывать своп памяти на диск. Он уж точно замедлит все работы сервера! |
innodb_additional_mem_pool_size | Размер памяти, используемой InnoDB, чтобы сохранить информацию словаря данных и другие внутренние структуры данных. Разумное значение для этого могло бы быть 2M, но чем больше таблиц используется, тем больше должен быть этот буфер. Если InnoDB исчерпает память в этом буфере, он начнет распределять память из операционной системы и будет писать предупреждающие сообщения в файл регистрации ошибок MySQL. |
innodb_file_io_threads | Число потоков ввода-вывода для файлов в InnoDB. Обычно это должно быть 4, но на Windows NT стоит увеличить значение. |
innodb_lock_wait_timeout | Время ожидания в
секундах, которое транзакция InnoDB может ждать блокировку прежде, чем
выполнить возврат. InnoDB автоматически обнаруживает тупики транзакции в
собственной таблице блокировки и прокручивает транзакцию назад. Если Вы
используете команду LOCK TABLES или другие
транзакционно-безопасные драйверы таблицы вместе с InnoDB в той же самой
транзакции, то может возникнуть тупик, на который InnoDB не сможет обратить
внимание. В таких случаях время ожидания может решить проблему. |
innodb_flush_method (доступно с версии 3.23.40 и выше)
| Значение по умолчанию для этого: fdatasync . Другая
опция: O_DSYNC . |
Предположим, что Вы установили MySQL и отредактировали файл my.cnf так, чтобы он содержал необходимые InnoDB параметры конфигурации. Перед запуском MySQL Вы должны проверить, что каталоги, которые Вы определили для файлов данных и журналов InnoDB, реально существуют, и что Вы имеете права доступа к этим каталогам. InnoDB не может создавать каталоги, только файлы в них. Проверьте также, что Вы имеете достаточно дискового пространства для данных и журналов.
Когда Вы теперь запускаете MySQL, InnoDB будет создавать Ваши файлы данных и журналы. При этом InnoDB выведет нечто вроде:
~/mysqlm/sql > mysqld InnoDB: The first specified data file /home/heikki/data/ibdata1 did not exist: InnoDB: a new database to be created! InnoDB: Setting file /home/heikki/data/ibdata1 size to 134217728 InnoDB: Database physically writes the file full: wait... InnoDB: Data file /home/heikki/data/ibdata2 did not exist: new to be created InnoDB: Setting file /home/heikki/data/ibdata2 size to 262144000 InnoDB: Database physically writes the file full: wait... InnoDB: Log file /home/heikki/data/logs/ib_logfile0 did not exist: new to be c reated InnoDB: Setting log file /home/heikki/data/logs/ib_logfile0 size to 5242880 InnoDB: Log file /home/heikki/data/logs/ib_logfile1 did not exist: new to be c reated InnoDB: Setting log file /home/heikki/data/logs/ib_logfile1 size to 5242880 InnoDB: Log file /home/heikki/data/logs/ib_logfile2 did not exist: new to be c reated InnoDB: Setting log file /home/heikki/data/logs/ib_logfile2 size to 5242880 InnoDB: Started mysqld: ready for connections
Новая база данных InnoDB теперь создана. Вы можете соединяться с сервером
MySQL обычными программами=клиентами MySQL, например, mysql
.
Когда Вы завершаете сервер MySQL командой mysqladmin shutdown,
InnoDB выведет примерно следующее:
010321 18:33:34 mysqld: Normal shutdown 010321 18:33:34 mysqld: Shutdown Complete InnoDB: Starting shutdown... InnoDB: Shutdown completed
Вы теперь можете рассматривать файлы данных и каталоги журналов, там Вы будете видеть созданные файлы. Каталог файлов регистрации будет также содержать маленький файл с именем ib_arch_log_0000000000. Этот файл результирует создание базы данных, после которого InnoDB прекратил архивирование файла регистрации. Когда MySQL снова будет запущен, вывод будет примерно таким:
~/mysqlm/sql > mysqld InnoDB: Started mysqld: ready for connections
Если что-то идет неправильно в создании базы данных InnoDB, Вы должны удалить все файлы, созданные InnoDB. Это означает все файлы данных, журналы, маленький сархивированный журнал, и в случае, если Вы уже создавали таблицы InnoDB, также соответствующие файлы .frm для этих таблиц из каталогов баз данных MySQL. Затем Вы можете попробовать создание базы данных InnoDB снова.
Предположим, что Вы запустили клиента MySQL командой mysql
test
. Чтобы создать таблицу в формате InnoDB, Вы должны определить
TYPE=InnoDB
в команде создания таблицы SQL:
CREATE TABLE CUSTOMER (A INT, B CHAR (20), INDEX (A)) TYPE = InnoDB;
Эта команда SQL создаст таблицу и индекс в столбце A
в
пространстве таблиц InnoDB, состоящем из файлов данных, которые Вы определили
в файле настроек my.cnf. Кроме того, MySQL создаст файл
`CUSTOMER.frm' в каталоге баз данных MySQL test. Внутренне,
InnoDB добавит к собственному словарю данных запись для таблицы
'test/CUSTOMER'
. Таким образом, Вы можете создавать таблицу с
тем же самым именем CUSTOMER
в другой базе данных MySQL, и имена
таблиц не будут сталкиваться внутри InnoDB.
Вы можете сделать запрос количества свободного пространства в пространстве
таблиц InnoDB, выдавая команду состояния таблицы MySQL для любой таблицы,
которую Вы создали с TYPE=InnoDB
. Затем количество свободного
места в пространстве таблиц появляется в разделе комментария таблицы в выводе
SHOW
. Конкретный пример:
SHOW TABLE STATUS FROM test LIKE 'CUSTOMER'
Обратите внимание, что статистика SHOW
относительно InnoDB
таблиц только приблизительна: она используется в оптимизации SQL. Но
зарезервированные размеры таблицы и индекса в байтах точны.
ОБРАТИТЕ ВНИМАНИЕ: DROP DATABASE
в настоящее время не
работает для InnoDB таблиц! Вы должны удалить таблицы индивидуально. Также
соблюдайте осторожность, чтобы не удалить или добавить файлы .frm к
Вашей базе данных InnoDB вручную: используйте для этого команды
CREATE TABLE
и DROP TABLE
. InnoDB имеет собственный
внутренний словарь данных, и Вы получите проблемы, если MySQL-файлы
.frm выйдут из синхронизации с внутренним словарем данных InnoDB.
InnoDB не имеет специальной оптимизации для отдельного создания индексов.
Самый быстрый способ изменять таблицу к InnoDB состоит в том, чтобы делать
вставки непосредственно в таблицу InnoDB, то есть использовать команду
ALTER TABLE ... TYPE=INNODB
или создать пустую таблицу InnoDB с
идентичными определениями и вставлять в нее строки с помощью команды
INSERT INTO ... SELECT * FROM ...
.
Чтобы получить лучший контроль над процессом вставки, удобно вставлять большие таблицы по кускам:
INSERT INTO newtable SELECT * FROM oldtable WHERE yourkey > something AND yourkey <= somethingelse;
После того, как все данные были вставлены, Вы можете переименовать таблицы.
В течение преобразования больших таблиц Вы должны установить большой размер буфера InnoDB, чтобы уменьшить дисковый ввод-вывод. Но не больше, чем 80% от размера физической памяти. Вы также должны установить большие журналы InnoDB и большой буфер файлов регистрации.
Удостоверьтесь, что Вы не исчерпаете пространство таблиц: InnoDB-базы
берут намного больше места, чем таблицы MyISAM. Если ALTER TABLE
исчерпает место, это запустит обратную перемотку, что может занять несколько
часов при дисковых операциях! Во вставках InnoDB использует буфер вставок,
чтобы объединить вторичные индексные записи на индексы в пакетах. Это
экономит много операций дискового ввода-вывода. В обратной перемотке никакой
такой механизм не используется, и она запросто может быть в 30 раз более
длинной, чем вставка.
В случае выхода обратной перемотки из-под контроля, если Вы не имеете ценных данных в Вашей базе данных, лучше, чтобы Вы уничтожили обработчики базы данных, все InnoDB-данные и журналы, а также всю InnoDB-таблицу .frm, после чего начали работу снова. Это выйдет быстрее, чем ждать миллионы дисковых вводов-выводов.
Вы не можете увеличивать размер файла данных InnoDB. Чтобы добавлять
больше места в пространство таблиц, Вы должны добавить новый файл данных.
Чтобы сделать это, Вы должны закрыть Вашу базу данных MySQL, отредактировать
файл настроек my.cnf, добавляя новый файл к
innodb_data_file_path
, и затем снова запустить MySQL.
В настоящее время Вы не можете удалять файл данных из InnoDB. Чтобы
уменьшить размер вашей базы данных, Вы должны использовать
mysqldump
для изготовления дампа всех Ваших таблиц, создать
новую базу данных и импортировать Ваши таблицы в новую базу данных.
Если Вы хотите изменять число или размер журналов InnoDB, Вы должны закрыть MySQL и удостовериться, что все закрывается без ошибок. Затем скопируйте старые журналы в безопасное место, на всякий случай (если что-то пошло неправильно в закрытии системы, и Вы будете нуждаться в них, чтобы восстановить базу данных). Удалите старые журналы из каталога журналов, отредактируйте файл настроек my.cnf и запустите MySQL снова. InnoDB сообщит Вам при запуске, что создает новые журналы.
Для создания двоичной копии Вашей базы данных, Вы должны делать следующее:
В настоящее время нет никакого интерактивного или инкрементного резервного инструмента, доступного для InnoDB, хотя они находятся в списке TODO.
В дополнение к принятию двоичных копий, описанных выше, Вы должны также регулярно создавать дампы Ваших таблиц с помощью команды mysqldump. Причина этого в том, что двоичный файл может быть разрушен тихо и незаметно. В случае использования дампа таблицы будут сохранены в текстовые файлы, которые являются читаемыми для человека и намного более простыми, чем двоичные файлы базы данных. Наблюдение искажения таблицы из таких файлов проще и, так как их формат более простой, возможность для серьезного нарушения целостности данных в них меньшая.
Хорошая идея состоит в том, чтобы делать дампы, в то же самое время, когда Вы делаете двоичную копию Вашей базы данных. Вы должны закрыть всю клиентуру, чтобы получить в дампе непротиворечивый образ всех Ваших таблиц. Затем Вы можете изготовить двоичную копию, и в результате Вы будете иметь непротиворечивый образ Вашей базы данных в двух форматах.
Чтобы быть способным восстановить Вашу базу данных InnoDB из двоичной копии, описанной выше, Вы должны выполнить Вашу базу данных MySQL с включенной общей регистрацией и архивированием файла регистрации MySQL. Здесь под общей регистрацией я имею в виду механизм регистрации сервера MySQL, который является независимым от файлов регистрации InnoDB.
Чтобы исправить аварийный отказ Вашего процесса сервера MySQL, Вы должны его просто перезапустить. InnoDB автоматически проверит файлы регистрации и выполнит восстановление базы данных. InnoDB будет автоматически откатывать нейтральные транзакции, которые были запущены во время аварийного отказа. В процессе восстановления InnoDB распечатает нечто вроде следующего:
~/mysqlm/sql > mysqld InnoDB: Database was not shut down normally. InnoDB: Starting recovery from log files... InnoDB: Starting log scan based on checkpoint at InnoDB: log sequence number 0 13674004 InnoDB: Doing recovery: scanned up to log sequence number 0 13739520 InnoDB: Doing recovery: scanned up to log sequence number 0 13805056 InnoDB: Doing recovery: scanned up to log sequence number 0 13870592 InnoDB: Doing recovery: scanned up to log sequence number 0 13936128 ... InnoDB: Doing recovery: scanned up to log sequence number 0 20555264 InnoDB: Doing recovery: scanned up to log sequence number 0 20620800 InnoDB: Doing recovery: scanned up to log sequence number 0 20664692 InnoDB: 1 uncommitted transaction(s) which must be rolled back InnoDB: Starting rollback of uncommitted transactions InnoDB: Rolling back trx no 16745 InnoDB: Rolling back of trx no 16745 completed InnoDB: Rollback of uncommitted transactions completed InnoDB: Starting an apply batch of log records to the database... InnoDB: Apply batch completed InnoDB: Started mysqld: ready for connections
Если Ваша база данных получает разрушение или есть дисковые сбои, Вы должны делать восстановление из копии. В случае искажения Вы должны сначала найти копию, которая не разрушена.
InnoDB реализует механизм контрольной точки, названный размытой контрольной точкой. InnoDB сбрасывает страницы изменяемой базы данных из буфера маленькими блоками, так что нет смысла выполнять сброс единым блоком, что надолго затормозит работу.
При восстановлении после аварийного отказа InnoDB ищет контрольную точку, отмеченную в журнале. InnoDB знает, что все модификации базы данных перед меткой уже представлены в дисковом образе. Затем InnoDB просматривает журналы вперед с места контрольной точки, применяя регистрируемые модификации.
InnoDB пишет журналы с учетом ротации. Все совершенные модификации, которые делают страницы базы данных в буфере отличными от образов на диске, должны быть доступны в журналах в случае, если InnoDB должен делать восстановление. Это означает, что, когда InnoDB начинает использовать новый журнал по схеме ротации, он должен удостовериться, что база данных на диске уже содержит все модификации. Другими словами, InnoDB должен делать контрольную точку, и часто это включает сброс изменяемой страницы базы данных на диск.
Вышеупомянутое объясняет, почему создание Ваших журналов очень большими может экономить дисковый ввод-вывод при введении контрольных точек. Может иметь смысл устанавливать полный размер журналов столь же большим, как буфер, или даже больше. Недостаток больших журналов в том, что восстановление после аварийного отказа может длиться долго потому, что будет присутствовать больший объем файла регистрации нужный, чтобы обратиться к базе данных.
Данные и журналы InnoDB двоично-совместимы на всех платформах, если формат
чисел с плавающей запятой на машинах тот же самый. Вы можете перемещать базу
данных InnoDB просто копируя все релевантные файлы, которые мы уже напечатали
в предыдущем разделе по поддержке базы данных. Если форматы чисел с плавающей
запятой на машинах различны, но Вы не использовали в Ваших таблицах типы
данных FLOAT
или DOUBLE
, процедура такая же: только
копируйте релевантные файлы. Если форматы различные, и Ваши таблицы содержат
данные с плавающей запятой, Вы должны использовать mysqldump и
mysqlimport, чтобы переместить эти таблицы.
В модели транзакции InnoDB цель была в том, чтобы объединить самые лучшие стороны мультиверсионной базы данных и традиционной блокировки с двумя фазами. Блокировка InnoDB работает на уровне строк и по умолчанию выполняет запросы чтения без блокировки, поскольку они обрабатываются непротиворечиво, в стиле Oracle. Таблица блокировки в InnoDB сохранена настолько компактно, что увеличение блокировки не нужно: обычно нескольким пользователям позволяют блокировать каждую строку в базе данных или любом произвольном подмножестве строк, без проблем с памятью у InnoDB.
В InnoDB все действия пользователя выполняются внутри транзакции. Если в
MySQL используется режим auto commit, то каждая инструкция SQL формирует
одиночную транзакцию. Если этот режим выключен, то мы можем думать, что
пользователь всегда имеет транзакцию открытой. Если он выдает SQL-инструкцию
COMMIT
или ROLLBACK
, которая заканчивает текущую
транзакцию, новая будет запущена. Обе инструкции выпустят все блокировки
InnoDB, которые были установлены в течение текущей транзакции.
COMMIT
означает, что изменения, сделанные в текущей транзакции,
стали постоянными и будут видимы другим пользователям. С другой стороны,
ROLLBACK
отменяет все модификации, сделанные текущей транзакцией.
Непротиворечивое чтение означает, что InnoDB использует поддержку разных версий, чтобы представить к запросу образ базы данных в некоторый момент времени. Запрос будет видеть изменения, сделанные точно теми транзакциями, которые совершились перед этой отметкой времени, и никаких изменений, сделанных позже или нейтральными транзакциями. Исключительная ситуация к этому правилу: запрос будет видеть изменения, сделанные транзакцией, которая выдает этот запрос.
Когда транзакция выдает первое непротиворечивое чтение, InnoDB назначает образ или отметку времени, которую использует все непротиворечивое чтение в той же самой транзакции. В образе будут отображены все транзакции, которые совершились перед его назначением. Таким образом, непротиворечивое чтение внутри той же самой транзакции, будет также непротиворечивым относительно нее. Вы можете получать более свежий образ для Ваших запросов, завершая текущую транзакцию и выдавая после этого новые запросы.
Непротиворечивое чтение представляет собой заданный по умолчанию режим, в
котором InnoDB обрабатывает инструкции SELECT
. Непротиворечивое
чтение не устанавливает никаких блокировок на таблицах, к которым обращается,
и, следовательно, другие пользователи свободны в их изменении в то же время.
Непротиворечивое чтение неудобно в некоторых обстоятельствах. Предположим,
что Вы хотите добавлять новую строку в вашу таблицу, CHILD
, и
удостовериться, что уже есть соответствующая запись в таблице
PARENT
.
Предположим, что Вы используете непротиворечивое чтение, чтобы читать
таблицу PARENT
и, действительно, смотрите записи. Вы теперь
можете безопасно добавлять соответствующую строку к таблице
CHILD
? Нет, потому, что легко может выйти так, что тем временем
некоторый другой пользователь удалил родительскую строку из таблицы
PARENT
, а Вы не знаете этого.
Решение состоит в том, чтобы выполнить SELECT
в режиме
блокировки, LOCK IN SHARE MODE
.
SELECT * FROM PARENT WHERE NAME = 'Jones' LOCK IN SHARE MODE;
Выполнение чтения в общем режиме означает, что мы читаем последние
доступные данные и устанавливаем общедоступную блокировку режима на строках,
которые мы читаем. Если последние данные принадлежат все же нейтральной
транзакции другого пользователя, мы будем ждать, пока та транзакция не
завершится. Общедоступная блокировка предотвращает от модифицирования или
удаления строки, которую мы читали, другими пользователями. После того, как
мы видим, что вышеупомянутый запрос возвращает родителя 'Jones'
,
мы можем безопасно добавлять его к таблице CHILD
и завершать
транзакцию. Этот пример показывает, как выполнить ссылочную целостность в
Вашем коде прикладной программы.
Давайте рассматривать другой пример: мы имеем целочисленное поле счетчика
в таблице CHILD_CODES
, который мы используем, чтобы назначить
уникальный идентификатор каждой записи, которую мы добавляем к таблице
CHILD
. Очевидно, что использование непротиворечивого чтения или
общедоступного режима чтения, чтобы читать представленное значение счетчика
никуда не годится: два пользователя базы данных могут видеть то же самое
значение для счетчика, и мы получим двойную ошибку ключа, когда мы добавляем
две записи с тем же самым идентификатором к таблице.
В этом случае имеются два хороших способа выполнить чтение и приращение
счетчика: (1) модифицировать счетчик сначала, увеличивая его на 1, и только
после того, как он будет прочитан, или (2) читать счетчик сначала с режимом
блокировки FOR UPDATE
и обновлять после этого:
SELECT COUNTER_FIELD FROM CHILD_CODES FOR UPDATE; UPDATE CHILD_CODES SET COUNTER_FIELD = COUNTER_FIELD + 1;
Вызов SELECT ... FOR UPDATE
будет читать последние доступные
данные, устанавливающие исключительные блокировки на каждой строке, которую
он читает. Таким образом, это устанавливает блокировку поиска SQL
UPDATE
для строк.
На уровне строки блокировка InnoDB использует алгоритм, названный блокировкой со следующим ключом. InnoDB делает блокировку уровня строки так, чтобы, когда он ищет или сканирует индекс таблицы, устанавливать общедоступные или исключительные блокировки на индексных записях. Таким образом, блокировки уровня строки более точно названы индексными блокировками для записи.
Блокировки InnoDB на индексных записях также воздействуют на промежуток
перед этой индексной записью. Если пользователь имеет общедоступную или
исключительную блокировку на записи R в индексе, то другой пользователь не
может вставлять новую индексную запись непосредственно перед R в индексном
порядке. Эта блокировка промежутков выполнена, чтобы предотвратить так
называемую проблему фантома. Предположим, что я хочу читать и блокировать все
записи children с идентификатором больше, чем 100 из таблицы
CHILD
, и модифицировать некоторое поле в выбранных строках.
SELECT * FROM CHILD WHERE ID > 100 FOR UPDATE;
Предположим, что имеется индекс на таблице, CHILD
на столбце
ID
. Мой запрос просмотрит тот индекс, начиная с первой записи,
где ID
больший, чем 100. Теперь, если бы набор блокировок на
индексных записях не блокировал бы вставки, сделанные в промежутках, новая
запись могла бы быть тем временем вставлена в таблицу. Если теперь я в моей
транзакции выполняю запрос:
SELECT * FROM CHILD WHERE ID > 100 FOR UPDATE;
То я буду видеть новую запись в результате обработки запроса. Это против принципа изоляции транзакций: транзакция должна быть способна выполниться так, чтобы данные, которые она читала, не изменились в течение транзакции. Если мы расцениваем набор строк как элемент данных, то новая фантомная запись разорвала бы этот принцип изоляции.
Когда InnoDB просматривает индекс, это может также блокировать промежуток
после последней записи в индексе. Это случается в предыдущем примере: набор
блокировок InnoDB предотвратит любую вставку в таблицу, где ID
был бы больше, чем 100.
Вы можете использовать блокировку следующего ключа, чтобы обеспечить уникальность регистрации Вашей прикладной программы: если Вы читаете Ваши данные в общем режиме и не смотрите дубликат для строки, которую Вы собираетесь вставлять, затем Вы можете безопасно вставлять Вашу строку и знать, что набор блокировок на преемнике Вашей строки в течение чтения предотвратит вставку дубликата для Вашей строки.
SELECT ... FROM ...
: непротиворечивое чтение, читает
образ базы данных и не устанавливает никаких блокировок.
SELECT ... FROM ... LOCK IN SHARE MODE
: устанавливает
общедоступную блокировку следующего ключа на всех индексных записях.
SELECT ... FROM ... FOR UPDATE
: устанавливает исключительные
блокировки следующего ключа на всем индексе.
INSERT INTO ... VALUES (...)
: устанавливает исключительную
блокировку на вставленной строке; обратите внимание, что эта блокировка не
является блокировкой следующего ключа и дает другим пользователям делать
вставки на промежутке перед вставленной строкой. Если происходит двойная
ошибка ключа, устанавливает общедоступную блокировку на
дублированной индексной записи.
INSERT INTO T SELECT ... FROM S WHERE ...
устанавливает
исключительную блокировку (non-next-key) на каждой строке, вставленной в
T
. Делает поиск на S
как непротиворечивое чтение,
но устанавливает общедоступные блокировки со следующим ключом на
S
, если включена регистрация MySQL. InnoDB должен в последнем
случае установить блокировки потому, что при восстановлении из копии каждая
инструкция SQL должна быть выполнена точно так же, как и в первый раз.
CREATE TABLE ... SELECT ...
выполняет SELECT
как непротиворечивое чтение или с общедоступными блокировками, как это
показано в предыдущем элементе.
REPLACE
будет выполнена подобно вставке, если не имеется
никакой проверки на пересечение по уникальному ключу. Иначе, исключительная
блокировка на следующем ключе будет применена к строке,
которая должна модифицироваться.
UPDATE ... SET ... WHERE ...
: устанавливает исключительную
блокировку следующего ключа на каждой записи, с которой сталкивается поиск.
DELETE FROM ... WHERE ...
: устанавливает исключительную
блокировку следующего ключа на каждой записи, с которой сталкивается поиск.
LOCK TABLES ...
: устанавливает блокировки таблицы. В
реализации MySQL уровень кода устанавливает эти блокировки. Автоматическое
обнаружение тупиков InnoDB не может обнаружить тупики, где включаются такие
блокировки таблицы. С тех пор как MySQL знает относительно блокировок уровня
строки, возможно, что Вы получаете блокировку таблицы на таблице, где другой
пользователь в настоящее время имеет блокировки уровня строки. Но это не
помещает целостности транзакции.InnoDB автоматически обнаруживает тупик транзакции и откатывает ту
транзакцию, чей запрос блокировки был последним при формировании тупика, то
есть цикл в графе ожидания транзакций. InnoDB не может обнаружить тупики, где
набор блокировок включается MySQL-инструкцией LOCK TABLES
, или
если набор блокировок включается в другом драйвере таблицы. Вы должны решить
эти ситуации, используя параметр innodb_lock_wait_timeout
в
my.cnf.
Когда InnoDB выполняет полную обратную перемотку транзакции, все блокировки транзакции будут сняты. Однако, если обратно в результате ошибки прокручена только одна инструкция SQL, часть этого набора блокировок может сохраниться, что не снимет весь набор блокировок.
Когда Вы устанавливаете непротиворечивое чтение, то есть выдаете обычную
инструкцию SELECT
, InnoDB даст Вашей транзакции точку timepoint,
согласно которой Ваш запрос видит базу данных. Таким образом, если транзакция
B удаляет строку и передает изменения после того, как Ваш timepoint был
назначен, то Вы не будете видеть удаление строки. Аналогично дело обстоит со
вставками и модификациями в базе.
Вы можете передвигать Ваш timepoint, завершая Вашу транзакцию и затем
делая другой SELECT
.
Это названо мультиверсионным управлением параллелизма.
Пользователь A Пользователь B set autocommit=0; set autocommit=0; Время | SELECT * FROM t; | empty set | INSERT INTO t VALUES (1, 2); v SELECT * FROM t; empty set COMMIT; SELECT * FROM t; empty set; COMMIT; SELECT * FROM t; ---------------------- | 1 | 2 | ----------------------
Таким образом, пользователь A видит строку, вставленную B только, когда B завершил вставку, и A завершил свою собственную транзакцию так, чтобы timepoint был передвинут на момент завершения работы B.
Если Вы хотите видеть самое новое состояние базы данных, Вы должны использовать чтение блокировки:
SELECT * FROM t LOCK IN SHARE MODE;
1. Если Unix top или Windows Task Manager показывает, что процент использования CPU с Вашей рабочей нагрузкой меньше, чем 70%, нагрузка, вероятно, связана диском. Возможно, Вы делаете слишком много транзакций, или буфер слишком маленький. Увеличение буфера может помочь, но не устанавливайте его большим, чем 80% физической памяти машины.
2. Неплохо соединить несколько модификаций в одну транзакцию. InnoDB должен сбрасывать файл регистрации на диск при каждой транзакции, если она вносит модификациями к базе данных. Так как быстродействие диска обычно в большинстве случаев низкое, транзакции будут задерживаться на соответствующее время, если диск не вводит в заблуждение Вашу операционную систему.
3. Если Вы можете пережить потерю некоторых последних
транзакций, Вы можете устанавливать в файле my.cnf параметр
innodb_flush_log_at_trx_commit
в 0. InnoDB попробует сбросить
файл регистрации во всяком случае раз в секунду, хотя это и не гарантируется.
4. Сделайте Ваши журналы большими, даже столь же большими, как буфер. Когда InnoDB наполняет журнал, он должен записать изменяемое содержание буфера на диск в контрольной точке. Маленькие журналы вызовут много ненужных записей. Недостаток больших журналов в том, что восстановление будет более длинное.
5. Буфер файлов регистрации должен быть большой, хотя бы 8 MB.
6. (Применимо с версии 3.23.39 и выше) В некоторых
версиях Linux и Unix, сброс файлов на диск вызовом Unix
fdatasync
и другими подобными методами происходит очень
медленно. Заданный по умолчанию метод InnoDB: функция fdatasync
.
Если Вы не удовлетворены этим, можете попробовать устанавливать
innodb_flush_method
в файле my.cnf в значение
O_DSYNC
, хотя O_DSYNC медленнее на большинстве систем.
7. В импортировании данных в InnoDB удостоверьтесь, что
MySQL не имеет настройки autocommit=1
. Каждая вставка требует
сброса протокола на диск. Так что установите перед импортируемыми данными в
своем файле строку:
set autocommit=0;
а после них строку:
commit;
Если Вы используете mysqldump с опцией --opt
, Вы
получите файлы дампа, которые должны быстро импортироваться в таблицу InnoDB,
даже без этих фокусов.
8. Остерегайтесь больших обратных перемоток массовых вставок: InnoDB использует буфер вставок, чтобы уменьшить медленный дисковый ввод-вывод во вставках, но в соответствующей обратной перемотке, такой механизм не используется. Связанная с диском обратная перемотка может занять в 30 раз больше времени, чем соответствующие вставки. Уничтожение процесса базы данных тут не будет помогать потому, что обратная перемотка начнется снова при запуске базы данных. Единственный способ избавиться от взбесившейся обратной перемотки состоит в том, чтобы увеличить буфер так, чтобы обратная перемотка стала ограничена только CPU и выполнилась быстро, или удалить целую базу данных InnoDB.
9. Остерегайтесь также других больших, связанных с
диском, операций. Используйте DROP TABLE
или
TRUNCATE
(в MySQL-4.0 и выше), чтобы освободить таблицу, а не
DELETE FROM yourtable
.
10. Используйте многострочный INSERT
, чтобы
уменьшить трафик между клиентом и сервером при вставке нескольких строк:
INSERT INTO yourtable VALUES (1, 2), (5, 5);
Этот совет, конечно, имеет силу для вставок в любой тип таблицы, а не только в InnoDB.
Начиная с версии 3.23.41, InnoDB включает монитор InnoDB, который печатает информацию относительно внутреннего состояния InnoDB. Эти данные полезны в настройке эффективности. Напечатанная информация включает данные относительно:
Вы можете запустить монитор InnoDB через следующую команду SQL:
CREATE TABLE innodb_monitor(a int) type = innodb;
И остановить его командой:
DROP TABLE innodb_monitor;
Синтаксис CREATE TABLE
только один из способов передать
команду на InnoDB через синтаксический анализатор MySQL SQL: созданная
таблица в общем не имеет отношения к монитору InnoDB. Если Вы закрываете базу
данных, когда монитор работает, и Вы хотите запустить монитор снова, Вы
должны удалить таблицу прежде, чем Вы сможете выдать новую команду
CREATE TABLE
, чтобы запустить монитор. Этот синтаксис может
изменяться в будущих версиях.
Типовой вывод монитора InnoDB:
================================ 010809 18:45:06 INNODB MONITOR OUTPUT ================================ -------------------------- LOCKS HELD BY TRANSACTIONS -------------------------- LOCK INFO: Number of locks in the record hash table 1294 LOCKS FOR TRANSACTION ID 0 579342744 TABLE LOCK table test/mytable trx id 0 582333343 lock_mode IX RECORD LOCKS space id 0 page no 12758 n bits 104 table test/mytable index PRIMARY trx id 0 582333343 lock_mode X Record lock, heap no 2 PHYSICAL RECORD: n_fields 74; 1-byte offs FALSE; info bits 0 0: len 4; hex 0001a801; asc ;; 1: len 6; hex 000022b5b39f; asc ";; 2: len 7; hex 000002001e03ec; asc ;; 3: len 4; hex 00000001; ... ----------------------------------------------- CURRENT SEMAPHORES RESERVED AND SEMAPHORE WAITS ----------------------------------------------- SYNC INFO: Sorry, cannot give mutex list info in non-debug version! Sorry, cannot give rw-lock list info in non-debug version! ----------------------------------------------------- SYNC ARRAY INFO: reservation count 6041054, signal count 2913432 4a239430 waited for by thread 49627477 op. S-LOCK file NOT KNOWN line 0 Mut ex 0 sp 5530989 r 62038708 sys 2155035; rws 0 8257574 8025336; rwx 0 1121090 1848344 ----------------------------------------------------- CURRENT PENDING FILE I/O'S -------------------------- Pending normal aio reads: Reserved slot, messages 40157658 4a4a40b8 Reserved slot, messages 40157658 4a477e28 ... Reserved slot, messages 40157658 4a4424a8 Reserved slot, messages 40157658 4a39ea38 Total of 36 reserved aio slots Pending aio writes: Total of 0 reserved aio slots Pending insert buffer aio reads: Total of 0 reserved aio slots Pending log writes or reads: Reserved slot, messages 40158c98 40157f98 Total of 1 reserved aio slots Pending synchronous reads or writes: Total of 0 reserved aio slots ----------- BUFFER POOL ----------- LRU list length 8034 Free list length 0 Flush list length 999 Buffer pool size in pages 8192 Pending reads 39 Pending writes: LRU 0, flush list 0, single page 0 Pages read 31383918, created 51310, written 2985115 ---------------------------- END OF INNODB MONITOR OUTPUT ============================ 010809 18:45:22 InnoDB starts purge 010809 18:45:22 InnoDB purged 0 pages
Некоторые замечания относительно этого вывода:
UNIV_SYNC_DEBUG
, определенном в univ.i.
InnoDB внутренне добавляет два поля к каждой строке, сохраненной в базе данных. Поле с 6 байтами сообщает идентификатор транзакции для последней транзакции, которая вставила или модифицировала строку. Также стирание внутренне обрабатывается как модификация, где будет установлен специальный бит в строке, чтобы отметить ее как удаленную. Каждая строка также содержит поле с 7 байтами, называемое указателем прокрутки. Он указывает на файл регистрации отмены, записываемый в сегмент обратной перемотки. Если строка модифицировалась, то запись файла регистрации отмены содержит информацию, необходимую, чтобы восстановить содержание строки.
InnoDB использует информацию в сегменте обратной перемотки, чтобы выполнить операции отмены, необходимые в обратной перемотке транзакции. InnoDB также применяет эту информацию, чтобы формировать более ранние версии строки для непротиворечивого чтения.
Файл регистрации отмены в сегменте обратной перемотки разделен на протоколы вставки и модификации. Протокол вставки необходим только в обратной перемотке транзакции и может быть отброшен, как только транзакция завершена. Протокол модификации используется также в непротиворечивом чтении и может быть отброшен, как только в нем исчезнет надобность (не будет транзакций, которым надо на его основе формировать более раннюю версию строки).
Вы должны не забыть регулярно закрывать Ваши транзакции. Иначе InnoDB не сможет отбрасывать данные из файлов регистрации отмены модификации, и сегмент обратной перемотки может стать слишком большим, заполняя пространство таблиц.
Физический размер записи файла регистрации отмены в сегменте обратной перемотки обычно меньший, чем соответствующая вставленная или модифицируемая строка. Вы можете использовать эту информацию, чтобы вычислить потребность в свободном месте в сегменте обратной перемотки.
В такой мультиверсионной схеме строка физически не будет удалена из базы данных немедленно, когда Вы удаляете ее инструкцией SQL. Только когда InnoDB сможет отбросить запись файла регистрации отмены модификации, написанную для стирания, он также сможет физически удалить соответствующую строку и индексные записи из базы данных. Эта операция удаления названа очисткой, и выполняется она очень быстро.
Каждая таблица InnoDB имеет специальный индекс, названный сгруппированным
индексом, где сохранены данные строк. Если Вы определяете PRIMARY
KEY
на Вашей таблице, то индексом первичного ключа будет как раз
именно сгруппированный индекс.
Если Вы не определяете первичный ключ для Вашей таблицы, InnoDB внутренне генерирует сгруппированный индекс, где строки упорядочиваются по идентификаторам, которые InnoDB назначает строкам в такой таблице. Идентификатор строки представляет собой поле с 6 байтами, которое увеличивается по мере вставки новых строк. Таким образом, строки будут упорядочены физически в порядке их вставки.
Обращение к строке через сгруппированный индекс быстро потому, что данные строки будут на той же самой странице, где завершился индексный поиск. Во многих БД данные традиционно сохранены на другой странице. Если таблица большая, сгруппированная индексная архитектура часто здорово уменьшает медленный дисковый ввод-вывод, когда она сравнивается с традиционным решением.
Записи в несгруппированных индексах (они же вторичные индексы) в InnoDB содержат значение первичного ключа для строки. InnoDB использует это значение ключа, чтобы искать строку из сгруппированного индекса. Обратите внимание, что, если первичный ключ длинный, вторичные индексы используют большее количество места в памяти.
Все индексы в InnoDB представляют собой B-деревья, где индексные записи сохранены в листе страницы дерева. Заданный по умолчанию размер индексной страницы равен 16 kB. Когда новые записи вставлены, InnoDB пробует оставлять 1/16 страницы свободной для будущих вставок и модификации индексных записей.
Если индексные записи вставлены в последовательном (возрастающем или убывающем) порядке, возникающие в результате индексные страницы будут относительно полными (15/16). Если записи вставлены в произвольном порядке, то страницы будут заполнены на 1/2-15/16. Если уровень заполнения (fillfactor) индексных страниц ниже 1/2, InnoDB пробует перестроить индексное дерево, чтобы освободить страницу.
Нормальной ситуацией в прикладной программе базы данных является то, что первичный ключ представляет собой уникальный идентификатор, и новые строки будут вставлены в порядке возрастания первичного ключа. Таким образом, вставки в сгруппированный индекс не требуют произвольного чтения с диска.
С другой стороны, вторичные индексы обычно неуникальны, и вставки во вторичные индексы выполняются в относительно произвольном порядке. Это вызвало бы много произвольного дискового ввода-вывода без специального механизма, используемого в InnoDB.
Если индексная запись была вставлена в неуникальный вторичный индекс, InnoDB проверит наличие страницы этого индекса в буферном пуле. Если это имеет место, InnoDB будет делать вставку непосредственно в индексную страницу. Но если индексная страница не найдена в буфере, InnoDB вставляет запись в специальную структуру буфера вставки.
Буфер вставок периодически объединяется с вторичными индексными деревьями в базе данных. Часто мы можем объединять несколько вставок на той же самой странице индексного дерева и, следовательно, экономить медленный дисковый ввод-вывод. Доказано на практике, что буфер вставок может ускорять вставки в таблицу до 15 раз.
Если база данных размещена почти полностью в основной памяти, то самый быстрый способ выполнять запросы состоит в том, чтобы использовать хэшируемые индексы. InnoDB имеет автоматический механизм, который контролирует индексные поиски, и если InnoDB обращает внимание, что запросы могли бы работать лучше с хэшируемым индексом, такой индекс будет автоматически сформирован.
Но такой индекс всегда формируется, основываясь на существующем индексе B-дерева таблицы. InnoDB может формировать хэш-индекс на префиксе любой длины ключа, определенного для B-дерева, в зависимости от того, какой образец InnoDB ищет на индексе B-дерева. Хэш-индекс может быть частичным: не требуется, чтобы целый индекс B-дерева кэшировался в буфере. InnoDB будет формировать хэшируемые индексы по требованию к тем страницам индекса, к которым часто обращаются.
После запуска базы данных, когда пользователь делает вставку в таблицу
T
, где был определен столбец с автоприращением, и пользователь
не задает явное значение для столбца, InnoDB выполняет SELECT
MAX(auto-inc-column) FROM T
и назначает полученное значение,
увеличенное на один, столбцу и счетчику автоприращеня. Мы говорим, что
счетчик для таблицы T
с автоприращением был инициализирован.
Обратите внимание, что, если пользователь определяет во вставке значение 0 столбцу с автоприращением, то InnoDB обрабатывает строку так, как если бы значение не было определено вообще.
После того, как счетчик автоприращения был инициализирован, если пользователь вставляет строку, где он явно определяет значение столбца, и это значение больше, чем текущее значение счетчика, он будет установлен в определенное значение столбца. Если пользователь явно не определяет значение, то InnoDB увеличивает счетчик на единицу и назначает новое значение столбцу.
Механизм автоприращения при назначении значений из счетчика обходит блокировки и обработки транзакции. Следовательно, Вы можете получать промежутки в последовательности чисел, если Вы откатываете транзакции, которые применяют числа из счетчика.
Поведение автоприращения не определено, если пользователь задает отрицательное значение столбцу, или если значение становится большим, чем максимальное целое число, которое может быть сохранено в определенном целочисленном типе.
В дисковом вводе-выводе InnoDB использует асинхронный ввод-вывод. В Windows NT он использует местный асинхронный ввод-вывод, обеспеченный операционной системой. В Unix InnoDB моделирует асинхронный ввод-вывод: InnoDB создает ряд потоков ввода-вывода, чтобы реализовать доступ к диску. В будущей версии мы добавим поддержку моделируемого ввода-вывода в Windows NT и местного асинхронного ввода-вывода на тех версиях Unix, которые его имеют.
В Windows NT InnoDB использует небуферизированный ввод-вывод. Это означает, что страницы, которые InnoDB читает или пишет, не будут буферизированы в кэше файлов операционной системы.
Начиная с версии 3.23.41, InnoDB использует новую методику сброса файлов, названную doublewrite. Это добавляет безопасности при сбоях, улучшает эффективность на большинстве разновидностей Unix и уменьшает потребность в операциях типа fsync.
Doublewrite означает, что InnoDB перед записью страниц в файл данных сначала пишет их в непрерывную область, названную буфером doublewrite. Только после записи в этот буфер InnoDB пишет страницы на их соответствующие позиции в файле данных. Если произошел сбой операционной системы в середине записи страницы, InnoDB будет при восстановлении брать хорошую копию страницы из буфера doublewrite.
Начиная с версии 3.23.41, Вы можете также использовать необработанный
дисковый раздел как файл данных, хотя это пока не было проверено. Когда Вы
создаете новый файл данных, Вы должны поместить ключевое слово
newraw
сразу после размера файла данных в
innodb_data_file_path
. Раздел должен быть >= того, что Вы
определили как размер. Обратите внимание, что 1M в InnoDB честно равен
1024x1024 байт, в то время как в дисковых спецификациях 1М как правило
означает всего лишь 1000000 байт.
innodb_data_file_path=hdd1:3Gnewraw;hdd2:2Gnewraw
Когда Вы запускаете базу данных снова, Вы ДОЛЖНЫ изменить ключевое слово
на raw
. Иначе InnoDB будет писать поверх Вашего раздела!
innodb_data_file_path=hdd1:3Graw;hdd2:2Graw
Имеется два типа опережающего чтения в InnoDB: последовательное и случайное. В последовательном чтении InnoDB обращает внимание на то, что образец доступа к сегменту в пространстве таблиц последователен. Затем InnoDB заранее читает пакет страниц из базы данных. В случайном чтении InnoDB обращает внимание на то, что некоторая область в пространстве таблиц полностью загружается в буфер. InnoDB заранее подгружает в буфер ее остатки.
Файлы данных, которые Вы определяете в файле конфигурации, формируют пространство таблиц InnoDB. В настоящее время Вы не можете непосредственно указывать, где именно будут размещены данные. Можно только утверждать, что в пространстве таблиц, начиная с нижнего конца.
Пространство таблиц состоит из базы данных страниц, чей заданный по умолчанию размер равен 16 КБ. Страницы сгруппированы в юлоки по 64 страницы. Файлы внутри пространства таблиц названы сегментами в InnoDB. Имя сегмента обратной перемотки несколько вводит в заблуждение потому, что он фактически хранит много сегментов в пространстве таблиц.
Для каждого индекса в InnoDB мы распределяем два сегмента: первый для узлов листьев B-дерева, второй для безлистных узлов.
Когда сегмент растет внутри пространства таблиц, InnoDB распределяет первые 32 страницы для него индивидуально. После этого InnoDB начинает распределять целые сегменты. InnoDB может добавлять к большому сегменту до 4 блоков страниц одновременно, чтобы гарантировать хорошую последовательность всех данных в нем.
Когда Вы выдаете запрос SHOW TABLE STATUS FROM ... LIKE ...
,
чтобы спросить о доступном свободном месте в пространстве таблиц, InnoDB
сообщит о месте, которое является пригодным для использования в полностью
свободных сегментах пространства таблиц. InnoDB всегда резервирует некоторые
сегменты для уборки и других внутренних целей, это зарезервированное место не
будет включено в свободное пространство.
Когда Вы удаляете данные из таблицы, InnoDB переделает соответствующие индексы B-дерева. В зависимости от ситуации будут освобождены страницы или сегмент. Удаление таблицы или всех строк из нее однозначно освободит место другим пользователям, но помните, что удаленные строки могут быть физически удалены только в операции очистки после того, как они больше не требуются в обратной перемотке транзакции или при непротиворечивом чтении.
Если имеются произвольные вставки или удаления в индексах таблицы, они могут стать фрагментированными. Под фрагментацией мы понимаем, что физическое расположение индексных страниц на диске не соответвует алфавитному расположению записей на страницах, или что имеется много неиспользуемых страниц в блоках с 64 страницами, которые были выделены этому индексу.
Можно ускорить индексные просмотры, если Вы периодически используете
mysqldump
для сброса дампа таблицы в текстовый файл, удаляете
таблицу и перезагружаете ее из дампа. Другой способ сделать дефрагменатцию
состоит в том, чтобы сменить командой ALTER
тип таблицы на
MyISAM
, а потом опять на InnoDB
. Обратите внимание,
что таблица типа MyISAM
должна расположиться в одном файле на
Вашей операционной системе.
Если вставки к индексу всегда делаются в порядке возрастания, и записи удалены только с конца, то алгоритм управления местом в файлах InnoDB гарантирует, что фрагментация в индексе происходить не будет.
Обработка ошибок в InnoDB не всегда такая же, как определяется в ANSI SQL. Согласно стандарту ANSI, любая ошибка в течение инструкции SQL должна вызвать обратную перемотку этой инструкции. InnoDB иногда откатывает только часть инструкции. Следующий список определяет обработку ошибок InnoDB.
'Table is full'
, и InnoDB отменит инструкцию SQL.
'Table handler error 1000000'
, и InnoDB отменит инструкцию SQL.
INSERT INTO ... SELECT ...
.
SHOW TABLE STATUS
не дает точную статистику на таблицах
InnoDB, кроме физического размера, зарезервированного таблицей. Число строк
только грубая оценка, используемая в оптимизации SQL.
CREATE TABLE T (A CHAR(20), B INT, UNIQUE (A(5))) TYPE = InnoDB;Если Вы создаете неуникальный индекс на префиксе столбца, InnoDB создаст индекс над целым столбцом.
INSERT DELAYED
не поддерживается для таблиц InnoDB.
LOCK TABLES
не знает о InnoDB блокировках
уровня строки. Это означает, что Вы можете получать блокировку уровня таблицы
на таблице, даже если там все еще существуют транзакции других пользователей,
которые имеют блокировки уровня строки на той же самой таблице. Таким
образом, Вашим операциям на этой таблице, вероятно, придется ждать, если они
сталкиваются с этими блокировками других пользователей. Также возможен тупик.
Однако, это не подвергает опасности целостность транзакции потому, что набор
блокировок уровней строк InnoDB будет всегда заботиться о целостности. Также
блокировка уровня таблицы защищает другие транзакции от приобретения большого
количества блокировок уровня строки (в противоречивом режиме блокировки)
на конкретной таблице.
BLOB
или TEXT
.
DELETE FROM TABLE
не регенерирует таблицу, но взамен удаляет
все строки одну за другой, что куда медленнее. В будущих версиях MySQL Вы
сможете использовать вызов TRUNCATE
, который является быстрым.
Автором и разработчиком InnoDB является Innobase Oy Website: http://www.innodb.com. Email: Heikki.Tuuri@innodb.com.
phone: 358-9-6969 3250 (office) 358-40-5617367 (mobile) InnoDB Oy Inc. World Trade Center Helsinki Aleksanterinkatu 17 P.O.Box 800 00101 Helsinki Finland
GRANT
и REVOKE
GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...] ON {tbl_name|*|*.*|db_name.*} TO user_name [IDENTIFIED BY 'password'] [, user_name [IDENTIFIED BY 'password'] ...] [REQUIRE {SSL|X509} [ISSUER issuer] [SUBJECT subject]] [WITH GRANT OPTION] REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...] ON {tbl_name|*|*.*|db_name.*} FROM user_name [, user_name ...]
GRANT
реализован в MySQL Version 3.22.11 или позже. Для более
ранних версий MySQL инструкция GRANT
не делает ничего.
Команды GRANT
и REVOKE
позволяют администраторам
системы создавать пользователей, предоставлять и отменять права на
MySQL-пользователей в четырех уровнях привилегий:
mysql.user
.
mysql.db
и
mysql.host
.
mysql.tables_priv
.
mysql.columns_priv
.Если Вы даете привилегии пользователю, который не существует, он будет
автоматически создан. За примерами по работе GRANT
обратитесь к
разделу "4.3.5 Добавление новых
пользователей к MySQL".
Для инструкций GRANT
и REVOKE
аргумент
priv_type
может быть определен как любой из следующего списка:
ALL PRIVILEGES FILE RELOAD ALTER INDEX SELECT CREATE INSERT SHUTDOWN DELETE PROCESS UPDATE DROP REFERENCES USAGE
ALL
представляет собой синоним для
ALL PRIVILEGES
. REFERENCES
пока не реализовано.
USAGE
в настоящее время представляет собой синоним для
``no privileges''. Это может быть применено, когда Вы хотите создать
пользователя, который не имеет никаких привилегий.
Чтобы отменять привилегию предоставленную командой grant,
используйте значение priv_type
параметра GRANT
OPTION
:
REVOKE GRANT OPTION ON ... FROM ...;
Значения priv_type
, которые Вы можете определять для таблицы:
SELECT
, INSERT
, UPDATE
,
DELETE
, CREATE
, DROP
,
GRANT
, INDEX
и ALTER
.
Значения priv_type
, которые Вы можете определять для столбца
(то есть, когда Вы используете аргумент column_list
):
SELECT
, INSERT
и UPDATE
.
Вы можете устанавливать глобальные привилегии, используя синтаксис
ON *.*
. Вы можете устанавливать привилегии базы данных,
используя синтаксис ON db_name.*
. Если Вы определяете
ON *
, и Вы имеете текущую базу данных, Вы установите привилегии
именно для этой базы данных. ПРЕДУПРЕЖДЕНИЕ: Если Вы
определяете ON *
, и Вы не имеете текущей базы данных,
Вы будете воздействовать на глобальные привилегии!
Чтобы приспосабливать предоставление прав на пользователей с произвольных
компьютеров, MySQL поддерживает определение значения user_name
в
форме user@host
. Если Вы хотите определять строку
user
или строку host
, содержащую специальные или
групповые символы (например, `-'), Вы можете цитировать имя
пользователя или хоста (например, 'test-user'@'test-hostname'
).
Вы можете определять групповые символы в hostname. Например,
user@"%.loc.gov"
применяется к user
для любого
компьютера в домене loc.gov
, а user@"144.155.166.%"
будет применено к user
с любой машины в сети
144.155.166
класса C.
Простая форма user
представляет собой синоним для
user@"%"
. ОБРАТИТЕ ВНИМАНИЕ: Если Вы позволяете
анонимным пользователям соединяться с сервером MySQL (что является значением
по умолчанию), Вы должны также добавить всех локальных пользователей как
user@localhost
потому, что иначе анонимная запись в таблице
mysql.user
будет применяться, когда пользователь попробует
зарегистрироваться на сервере MySQL с локальной машины! Анонимные
пользователи определены вставкой записей с User=''
в таблицу
mysql.user
. Вы можете проверять, применяется ли это у Вас,
выполняя такой запрос:
mysql> SELECT Host,User FROM mysql.user WHERE User='';
В настоящий момент GRANT
поддерживает имена хоста, базы
данных, таблицы и столбца длиной только до 60 символов. Имя пользователя
может быть длиной до 16 символов.
Привилегии для таблицы или столбца сформированы из логического ИЛИ (OR)
привилегий в каждом из четырех уровней привилегии. Например, если таблица
mysql.user
определяет, что пользователь имеет глобальную
привилегию select, это не может быть отменено записью на
других уровнях доступа!
Привилегии для столбца могут быть вычислены следующим образом:
global privileges OR (database privileges AND host privileges) OR table privileges OR column privileges
В большинстве случаев Вы предоставляете права пользователю только в одном из уровней привилегии, так что обычно это просто. Детали проверяющей привилегии процедуры подробно рассмотрены в разделе "4.2 Общие проблемы защиты и система привилегий доступа MySQL".
Если Вы предоставляете привилегии для комбинации user/hostname, которая не
существует в таблице mysql.user
, запись будет добавлена и
останется там пока ее не удалят командой DELETE
. Другими
словами, GRANT
может создавать записи в таблице
user
, но REVOKE
не будет удалять их. Вы должны
делать это явно, используя вызов DELETE
.
В MySQL Version 3.22.12 или позже, если новый
пользователь создан, или если Вы имеете глобальные привилегии, пароль
пользователя будет установлен в пароль, определенный предложением
IDENTIFIED BY
, если оно задано. Если пользователь уже имел
пароль, он будет заменен новым.
ПРЕДУПРЕЖДЕНИЕ: Если Вы создаете нового пользователя, но
не определяете предложение IDENTIFIED BY
, пользователь не имеет
никакого пароля. Это опасно.
Пароли также могут быть установлены командой SET PASSWORD
.
Подробности в разделе "5.5.6 Синтаксис
SET
".
Если Вы предоставляете привилегии для базы данных, запись в таблице
mysql.db
будет создана, если необходимо. Когда все привилегии
для базы данных будут удалены с помощью REVOKE
, эта запись тоже
будет удалена автоматически.
Если пользователь не имеет привилегий на таблице, данная таблица не
отображается вообще, когда пользователь запрашивает список таблиц (например,
инструкцией SHOW TABLES
).
Предложение WITH GRANT OPTION
дает пользователю способность
передать другим пользователям любые привилегии, которые этот пользователь
имеет в определенном уровне доступа. Вы должны быть внимательным к тому, кому
Вы даете привилегию grant, поскольку два пользователя с
различными привилегиями могут быть способны соединить свои привилегии!
Вы не можете предоставлять другому пользователю привилегию, которую Вы не имеете сами. Привилегия 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
, чтобы сервер перезагрузил все
таблицы предоставления привилегий.
Самые большие различия между ANSI SQL и MySQL
версиями оператора GRANT
:
TRIGGER
, EXECUTE
и
UNDER
из ANSI SQL.
INSERT
только на части
столбцов в таблице, Вы можете выполнять инструкции INSERT
относительно таблицы: столбцы, для которых Вы не имеете привилегию
INSERT
будут установлены к их значениям по умолчанию. ANSI SQL
требует, чтобы Вы имели привилегию INSERT
на всех столбцах.
REVOKE
или правкой таблиц предоставления привилегий MySQL.Имеются несколько различий между использованием имен и паролей MySQL и Unix или Windows:
-u
или --user
. Это означает, что Вы не можете
делать базу данных безопасной всегда, если все имена пользователей MySQL не
имеют паролей. Любой может пытаться соединиться с сервером, используя любое
имя, и это получиться, если использовано имя, которое не имеет пароля.
Пользователи MySQL и их привилегии обычно создаются командой
GRANT
. Подробности в разделе "4.3.1
Синтаксис GRANT
и REVOKE
".
Когда Вы входите в систему на сервере MySQL с помощью клиента командной
строки, Вы должны определить пароль с помощью опции
--password=your-password
. Подробности изложены в разделе
"4.2.7 Связь с сервером 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 не имеет ограничений на длину пароля.
При запуске mysqld
все содержание таблиц предоставления
привилегий читается в память и становится действующим.
Модификации к таблицам предоставления, которые Вы выполняете используя
GRANT
, REVOKE
или SET PASSWORD
вступают в силу немедленно.
Если Вы изменяете таблицы предоставления вручную (используя операторы
INSERT
, UPDATE
), Вы должны выполнить инструкцию
FLUSH PRIVILEGES
или запустить
mysqladmin flush-privileges
, или mysqladmin reload
,
чтобы сообщить, что сервер должен перезагрузил таблицы предоставления. Иначе
Ваши изменения не будут иметь никакого эффекта, пока Вы не перезапустите
сервер. Если Вы изменяете таблицы предоставления вручную, но забываете
перезагружать привилегии, Вы будете часто задаваться вопросом, почему Ваши
изменения не делают вообще ничего!
Когда сервер обращает внимания, что таблицы предоставления были изменены, на существующие подключения пользователей это воздействуют следующим образом:
USE db_name
.Изменения глобальных привилегий и пароля воздействуют, когда пользователь соединится в следующий раз.
После установки MySQL Вы устанавливаете начальные привилегии доступа
вызовом скрипта scripts/mysql_install_db
. Подробности в разделе
"2.3.1 Обзор быстрой установки".
Скрипт mysql_install_db
запускает сервер mysqld
и
устанавливает следующие привилегии:
root
создан как суперпользователь,
который может делать что угодно. Подключения должны быть обязательно с
локального компьютера. ОБРАТИТЕ ВНИМАНИЕ: начальный пароль
для root
пуст, так что любой может соединяться как
root
без пароля и предоставлять все привилегии.
test
, или их имя начинается с
test_
. Подключения должны быть с локального компьютера. Это
означает, что любой локальный пользователь может соединяться без пароля и
обрабатываться как анонимный пользователь.
mysqladmin shutdown
или mysqladmin processlist
.
ОБРАТИТЕ ВНИМАНИЕ: заданные по умолчанию привилегии иные для Windows. Подробности в разделе " 2.6.2.3 Запуск MySQL под Windows".
Первое, что следует сделать, это определить пароль для MySQL-пользователя
root
. Вы можете сделать это следующим образом (обратите
внимание, что Вы определяете пароль, используя функцию
PASSWORD()
):
shell> mysql -u root mysql mysql> UPDATE user SET Password=PASSWORD('new_password') WHERE user='root'; mysql> FLUSH PRIVILEGES;
Вы можете, в MySQL версии 3.22 и выше, использовать инструкцию
SET PASSWORD
:
shell> mysql -u root mysql mysql> SET PASSWORD FOR root=PASSWORD('new_password');
Другой способ устанавливать пароль: применить команду
mysqladmin
:
shell> mysqladmin -u root password new_password
Только пользователи с доступом на чтение/запись к базе данных
mysql
могут изменять пароль для других пользователи. Все
нормальные пользователи (не анонимные) могут менять только их собственный
пароль с помощью вышеупомянутых команд или вызовом
SET PASSWORD=PASSWORD('new password')
.
Обратите внимание, что, если Вы модифицируете пароль непосредственно в
таблице user
, используя первый метод, Вы должны сообщить, чтобы
сервер заново прочитал таблицы предоставления привилегий (команда
FLUSH PRIVILEGES
), иначе изменение будет не замечено.
Как только пароль root
был установлен, Вы должны использовать
его при соединении с сервером.
Изучение скрипта scripts/mysql_install_db
весьма пригодится
при сборе информации по созданию и настройке других пользователей.
Если Вы хотите, чтобы начальные привилегии были иными, чем те, которые
только что я описал, Вы можете изменять скрипт mysql_install_db
прежде, чем Вы его выполните.
Чтобы освежить таблицы
предоставления привилегий полностью (пересоздать их заново), удалите все
файлы `.frm', `.MYI' и `.MYD' в каталоге,
содержащем базу данных mysql
. Это каталог с именем
`mysql' в каталоге баз данных, который будет перечислен, когда
Вы выполняете mysqld --help
. Затем выполните скрипт
mysql_install_db
, возможно, после его редактирования, чтобы
иметь те привилегии, которые Вы хотите установить.
ОБРАТИТЕ ВНИМАНИЕ: Для MySQL версий старше, чем 3.22.10,
Вы не должны удалить файлы `.frm'. Если Вы случайно сделаете это, Вы
должны скопировать их обратно из Вашего дистрибутива MySQL перед выполнением
mysql_install_db
.
Вы можете добавлять пользователей двумя различными путями: используя
инструкции GRANT
или непосредственно управляя таблицами MySQL.
Имеются также много программ, например, phpmyadmin
, которые
могут использоваться, чтобы создать и администрировать пользователей.
Примеры ниже показывают, как использовать клиент mysql
, чтобы
установить новых пользователей. Эти примеры принимают, что привилегии
установлены согласно значениям по умолчанию, описанным в предыдущем разделе.
Это означает, что, чтобы делать изменения, Вы должны быть зарегестрированы на
той же самой машине, где работает сервер mysqld
, Вы должны
соединиться как MySQL-пользователь root
, и он должен иметь
привилегию insert для базы данных mysql
, а
также административную привилегию reload. Также, если Вы
изменили пароль для root
, Вы должны определить его в командах.
Вы можете добавлять новых пользователей, выдавая инструкции
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'
(версии до версии 3.22.11
имели меньшее количество столбцов привилегий). Для пользователя
admin
применен более удобный синтаксис INSERT
,
который является доступным, начиная с версии 3.22.11 и выше.
Обратите внимание, что, чтобы установить суперпользователя, Вы должны
только создать запись таблицы user
с набором полей привилегий,
выставленных в 'Y'
. Никаких записей в таблицах db
или host
не требуется.
Столбцы привилегии в таблице user
не были установлены явно в
последней инструкции INSERT
(для пользователя
dummy
), так что им будет установлено значение по умолчанию
'N'
.
Следующий пример добавляет пользователя 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';
Чтобы установить привилегии пользователя, изменяя таблицы предоставления
привилегий непосредственно, выполните эти команды (обратите внимание на вызов
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
, но только когда он обращается с соответствующих
компьютеров. Как обычно, когда таблицы предоставления привилегий изменяются
непосредственно, сервер должен перезагрузить их.
Если Вы хотите давать специфический доступ пользователю с любой машины в
данном домене, Вы можете выдать инструкцию GRANT
таким образом:
mysql> GRANT ... ON *.* TO myusername@"%.mydomainname.com" IDENTIFIED BY 'mypassword';
Чтобы сделать ту же самую работу, изменяя таблицы предоставления привилегий непосредственно, сделайте так:
mysql> INSERT INTO user VALUES ('%.mydomainname.com', 'myusername', PASSWORD('mypassword'),...); mysql> FLUSH PRIVILEGES;
Вы можете также использовать xmysqladmin
,
mysql_webadmin
и xmysql
, чтобы вставлять, изменять
и модифицировать значения в таблицах предоставления. Вы можете найти эти
утилиты в каталоге
http://www.mysql.com/Downloads/Contrib Web-сайта MySQL.
В большинстве случаев Вы должны использовать GRANT
, чтобы
установить Ваших пользователей и их пароли, так что следующее касается только
пользоваателей профессионального уровня.
Примеры в предшествующих разделах иллюстрируют важный принцип: когда Вы
сохраняете непустой пароль, используя инструкции INSERT
или
UPDATE
, Вы должны использовать функцию PASSWORD()
для его шифрования. Это потому, что таблица user
хранит пароли в
зашифрованной форме, а не как открытый текст. Если Вы забываете этот факт,
Вы, вероятно, будет пытаться устанавливать пароли подобно этому примеру:
shell> mysql -u root mysql mysql> INSERT INTO user (Host,User,Password) VALUES('%','jeffrey','biscuit'); mysql> FLUSH PRIVILEGES;
Результат: открытый текст 'biscuit'
будет сохранен как пароль
в таблице user
. Когда пользователь 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'));
Вы должны также использовать функцию PASSWORD()
, когда Вы
применяете инструкции SET 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.
Нецелесообразно определять Ваш пароль так, что его могут увидеть другие пользователи. Методы, которые Вы можете использовать, чтобы определить Ваш пароль, когда Вы выполняете программы-клиенты, перечислены ниже, наряду с оценкой рисков каждого метода:
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
включают
опцию, чтобы отобразить среду управления процессами. Ваш пароль будет видим
всем желающим использовать такую команду. Даже на системах без такой версии
ps
неблагоразумно считать, что не имеется никакого другого
метода наблюдать среды процесса.В целом, самые безопасные методы состоят в том, чтобы иметь запрос программы-клиента для пароля или определять пароль в правильно защищенном файле личных настроек .my.cnf.
Оптимизация представляет собой сложную задачу потому, что в конечном счете требуется понимание целой системы. В то время, как можно сделать некоторую локальную оптимизацию с небольшими знаниями относительно Вашей системы или прикладной программы, серьезная оптимизация требует значительных знаний.
Эта глава пробует объяснить и дать некоторые примеры различных способов оптимизировать MySQL. Помните, однако, что всегда имеются некоторые дополнительные способы сделать Вашу систему еще чуть быстрее.
Наиболее важная часть для получения быстрой системы: базисный проект. Вы также должны знать то, какие дела Ваша система будет делать, каковы Ваши узкие места на этом пути.
Наиболее общие узкие места:
Поскольку MySQL использует чрезвычайно быструю блокировку таблицы (много чтений и одна запись), самая большая остающаяся проблема: смесь устойчивого потока вставок и медленного выбора данных в той же самой таблице.
Считается, что для огромного числа систем чрезвычайно быстрая эффективность в других случаях делает этот выбор правильным. Этот случай обычно также решаем при наличии нескольких копий таблицы, но требуется большее количество усилий и аппаратных средств.
Авторы также работают над некоторыми расширениями, чтобы решить эту проблему для некоторых общих ниш прикладных программ.
Потому, что все серверы SQL выполняют различные части SQL, требуется немалая работа, чтобы писать переносные прикладные программы SQL. Для очень простых выборов и вставок это очень просто, но чем дальше, тем труднее становится нормальное программирование.
Чтобы делать сложную прикладную программу переносной, Вы должны выбрать ряд серверов SQL, с которыми она должна работать.
Вы можете использовать MySQL программу crash-me/web-page http://www.mysql.com/information/crash-me.php, чтобы найти функции, типы и ограничения, которые Вы можете использовать с выбором сервера базы данных. Crash-me проверяет далеко не все возможное, но тест выполнен для 450 задач.
Например, Вы не должны иметь имена столбцов более длинными, чем 18 символов, если Вы хотите использовать Informix или DB2.
Тесты и программа MySQL crash-me являются очень независимыми от базы данных. Изучение этих программ может помочь Вам в написании своих прикладных программ, независимых от базы данных. Эталонные тесты могут быть найдены в каталоге sql-bench дерева исходников MySQL. Они написаны на Perl с интерфейсом базы данных DBI (который решает проблемы доступа).
Результаты тестов есть на http://www.mysql.com/information/benchmarks.html.
Как Вы можете видеть в этих результатах, все базы данных имеют некоторые слабые пункты. То есть они имеют различные компромиссы проекта, которые ведут к различному поведению.
Если Вы боретесь за независимость базы данных, Вы должны получить данные по проблемным зонам каждого сервера SQL. MySQL ОЧЕНЬ быстр в поиске и модифицировании, но будет иметь проблему при смешивании медленных чтений и записей на той же самой таблице. Oracle, с другой стороны, имеет большую проблему, когда Вы пробуете обращаться к строкам, которые Вы недавно модифицировали (пока их не сбросят на диск). Базы данных с транзакциями вообще не очень хороши при производстве итоговых таблиц из таблиц файла регистрации, поскольку в этом случае блокировка строки почти бесполезна.
Чтобы сделать Вашу прикладную программу по-настоящему независимой от базы данных, Вы должны определить простой интерфейс, через который Вы управляете вашими данными. Поскольку C++ доступен на большинстве систем, имеет смысл использовать интерфейс классов C++ к базам данных.
Если Вы используете некоторое специфическое свойство для некоторой базы
данных (подобно команде REPLACE
в MySQL), Вы должны
предусмотреть метод для других серверов SQL, чтобы выполнить то же самое
свойство (но медленнее). С MySQL Вы можете использовать синтаксис
/*! */
, чтобы добавить MySQL-специфические ключевые слова к
запросу. Код внутри /**/
будет обрабатываться как комментарий
большинством других серверов SQL.
Если высокая эффективность более важна, чем точность, как в некоторых прикладных программах для интернета, можно создать уровень прикладной программы, который кэширует все результаты, чтобы дать Вам даже более высокую эффективность. Позволяя старым результатам выдыхаться через некоторое время, Вы можете хранить кэш, приемлемо свежим. Это совершенно хорошо в случае чрезвычайно высокой загрузки, когда Вы можете динамически увеличивать кэш и повышать время ожидания, пока ситуация не вернется к норме.
В этом случае информация для создания новой таблицы должна содержать еще и информацию относительно начального размера кэша и то, как часто таблица обычно должна обновиться.
Вот что пишут авторы пакета о том, как создавалась эта СУБД:
В ходе начальной разработки, свойства MySQL были сделаны такими, чтобы удовлетворить нашего самого большого заказчика. Он обрабатывает данные для самых больших розничных продавцов в Швеции.
Из всех магазинов мы получаем еженедельно резюме всех транзакций по картам скидок и призов. Требуется обеспечить полезную информацию для владельцев магазинов, чтобы помочь им понять, как их рекламные кампании воздействуют на их заказчиков.
Данные огромны (приблизительно 7 миллионов итоговых транзакций в месяц), и мы имеем данные за последние 4-10 лет, которые должны представить пользователям. Мы получили еженедельно запросы от заказчиков, что они хотят иметь мгновенный доступ к новым отчетам из этих данных.
Мы решили это, сохраняя всю информацию за месяц в сжатых таблицах. Мы имеем набор простых макрокоманд (скриптов), который генерирует итоговые таблицы, сгруппированные в соответствии с различными критериями (product group, customer id, store, ...) из таблиц транзакции. Отчеты представляют собой Web-страницы, которые динамически генерируются маленьким скриптом на Perl, который анализирует Web-страницу, выполняет инструкции SQL и вставляет результаты. Мы использовали бы взамен PHP или mod_perl, но они не были доступны в то время.
Для графических данных мы написали на C
простой инструмент,
который может производить GIF-файлы, основываясь на результате запроса SQL (с
некоторой обработкой результата). Это также динамически выполняется из
скрипта на Perl, который анализирует HTML-файлы.
В большинстве случаев новый отчет может быть выполнен, просто копируя существующий скрипт и изменяя запрос SQL в нем. В некоторых случаях мы будем должны добавить большее количество полей к существующей таблице или сгенерировать новую, но это также просто, поскольку мы храним все таблицы транзакций на диске. В настоящее время мы имеем по крайней мере 50G таблиц транзакций и порядка 200G других данных заказчика.
Мы также позволяем нашим заказчикам обращаться к итоговым таблицам непосредственно через ODBC так, чтобы продвинутые пользователи могли самостоятельно экспериментировать с данными.
Мы не имели проблем с обработкой данных на Sun Ultra SPARCstation (2x200 Mhz). Недавно был проведен апгрейд до 2 CPU 400 Mhz UltraSPARC, и мы теперь планируем запускать транзакции обработки на уровне изделия товара, что означает десятикратное увеличение данных.
Мы также экспериментируем с Intel-Linux, чтобы быть способными получить большее количество более дешевой мощности CPU. Теперь, когда мы имеем двоичный переносимый формат базы данных (введен в Version 3.23), мы начнем использовать это для некоторых частей прикладной программы.
Этот раздел должен содержать техническое описание эталонного набора тестов
MySQL и теста crash-me
, но пока подробное руководство еще никем
не написано (в том числе и авторами пакета). Так что говорить о нем рано. В
настоящее время Вы можете получить хорошую помощь относительно эталонного
теста, рассматривая код и результаты в каталоге sql-bench
дистрибутива исходников MySQL.
Этот эталонный набор, как предполагается, является эталонным тестом, который сообщит любому пользователю, что именно данная реализация SQL выполняет хорошо или плохо.
Обратите внимание, что этот эталонный тест однопоточный, так что он измеряет минимальное время для операций. В будущем планируется добавление поддержки многопоточной обработки.
Например, (запуск на машине с NT 4.0):
Чтение 2000000 строк по индексу | Секунд |
mysql | 367 |
mysql_odbc | 464 |
db2_odbc | 1206 |
informix_odbc | 121126 |
ms-sql_odbc | 1634 |
oracle_odbc | 20800 |
solid_odbc | 877 |
sybase_odbc | 17614 |
Вставка 350768 строк | Секунд |
mysql | 381 |
mysql_odbc | 619 |
db2_odbc | 3460 |
informix_odbc | 2692 |
ms-sql_odbc | 4012 |
oracle_odbc | 11291 |
solid_odbc | 1801 |
sybase_odbc | 4802 |
В вышеупомянутом тесте MySQL был выполнен с 8M индексным кэшем.
Мы имеем несколько больше эталонных результатов на http://www.mysql.com/information/benchmarks.html.
Обратите внимание, что Oracle не включен потому, что компания-разработчик потребовала удалить эти данные. Причины такого отношения к независимым измерениям производительности могут быть вызваны лишь откровенным завышением характеристик сервера компанией Oracle.
Чтобы выполнить эталонный набор, Вы должны загрузить исходники MySQL, установить драйвер perl DBI для базы данных, которую Вы хотите проверить, и затем отдать команды:
cd sql-bench perl run-all-tests --server=#
Здесь # задает один из поддержанных серверов. Вы можете получить список
всех параметров и поддержанных серверов командой run-all-tests --help
.
Тест crash-me
может определить, какие
свойства база данных поддерживает, и перечень фактических возможностей и
ограничений. Например, это определяет:
VARCHAR
Результаты теста crash-me для большого набора разных баз данных можно найти на http://www.mysql.com/information/crash-me.php.
Вы должны использовать эталонный тест, чтобы выяснять, где находятся узкие места. Исправляя это (или заменяя узкое место фиктивным модулем), Вы можете затем легко идентифицировать следующее узкое место и так далее. Даже если полная эффективность для Вашей прикладной программы достаточна, Вы должны по крайней мере сделать план каждого узкого места и решить, как его расширить, если возникнет такая потребность.
Для примера переносных эталонных программ рассмотрите эталонный набор MySQL. Подробности в разделе "5.1.4 Пакет тестов MySQL Benchmark Suite". Вы можете брать любую программу из этого набора и изменять ее для Ваших потребностей. Делая это, Вы можете опробовать различные решения Вашей проблемы и теста, который в самом деле является самым быстрым решением для Вас.
Некоторые проблемы происходят только тогда, когда система очень тяжело загружена. В каждом из этих случаев это обычно проблема с базисным проектом (просмотр таблицы НЕ хорош при высокой загрузке) или есть трудности с OS/Library. Большинство этих случаев было бы НАМНОГО проще исправить, если система еще не запущена в работу.
Чтобы избежать подобных проблем, Вы должны тестировать прикладную программу при самой плохой возможной загрузке! Вы можете использовать для этого Super Smack, который доступен по адресу http://www.mysql.com/Downloads/super-smack/super-smack-1.0.tar.gz.
SELECT
и разных запросовСначала, одна вещь, которая воздействует на все запросы: более сложная установка систем разрешений, которую Вы имеете, усложняет и замедляет работу. В настройках не должно быть ничего лишнего. Все дополнительные довески и добавки замедляют работу системы (порой неожиданно сильно!). Как говорил один из моих преподавателей в университете, на парте должны быть только бумага, ручка и Ваши мозги.
Если Вы не имеете никаких выполненных инструкций GRANT
, MySQL
оптимизирует проверку разрешений.
Если Ваша проблема связана с некоторой явной функцией MySQL, Вы можете всегда сделать это в пользователе MySQL:
mysql> select benchmark(1000000,1+1); +------------------------+ | benchmark(1000000,1+1) | +------------------------+ | 0 | +------------------------+ 1 row in set (0.32 sec)
Этот пример показывает, что MySQL может выполнять 1000000 операций
сложения (+
) за 0.32 секунды на PentiumII 400MHz
.
Все функции MySQL должны быть очень хорошо оптимизированы, но могут
иметься некоторые исключительные ситуации, и вызов
benchmark(loop_count,expression)
представляет собой хороший
инструмент, чтобы выяснить, связана ли эта проблема с Вашим запросом.
EXPLAIN
(получение информации о SELECT
)EXPLAIN tbl_name or EXPLAIN SELECT select_options
EXPLAIN tbl_name
представляет собой синоним для
DESCRIBE tbl_name
или SHOW COLUMNS FROM tbl_name
.
Когда Вы перед SELECT
задаете ключевое слово
EXPLAIN
, MySQL объясняет, как он обработал бы
SELECT
, обеспечивая информацию относительно того, как таблицы
будут соединены, и в каком порядке.
С помощью EXPLAIN
Вы можете видеть, когда Вы должны добавить
индексы к таблицам, чтобы получить более быстрый SELECT
, который
использует индексы, чтобы найти записи. Вы можете также видеть, соединяет ли
оптимизатор таблицы в оптимальном порядке. Чтобы вынуждать оптимизатор
использовать специфический порядок объединения для инструкции
SELECT
, добавьте предложение STRAIGHT_JOIN
.
Для непростых объединений EXPLAIN
возвратит строку информации
для каждой таблицы, используемой в инструкции SELECT
. Таблицы
перечислены в том порядке, в каком они читались бы. MySQL читает строку из
первой таблицы, затем находит строку соответствий во второй таблице, затем в
третьей таблице и так далее. Когда все таблицы обработаны, MySQL выводит
выбранные столбцы и возвращается через список таблицы, пока не будет найдена
таблица, для которой там больше соответствующих строк. Следующая строка
читается из этой таблицы, и процесс продолжается со следующей таблицей.
Вывод из EXPLAIN
включает в себя следующие столбцы:
table
type
possible_keys
possible_keys
указывает, какие индексы MySQL мог бы
использовать, чтобы найти строки в этой таблице. Обратите внимание, что этот
столбец полностью не зависит от порядка таблиц. Это означает, что некоторые
из ключей в possible_keys не могут быть пригодны для использования
практически со сгенерированным порядком таблицы. Если этот столбец пуст, не
имеется никаких релевантных индексов. В этом случае, Вы можете улучшить
эффективность Вашего запроса, исследуя предложение WHERE
, чтобы
увидеть, обращается ли оно к некоторому столбцу или столбцам, которые были бы
подходящими для индексации. Если так, создайте соответствующий индекс, и
проверьте запрос с помощью EXPLAIN
снова. Чтобы увидеть, какие
индексы таблица имеет, вызовите SHOW INDEX FROM tbl_name
.
key
key
указывает ключ, который MySQL фактически решил
использовать. Если индекс не выбран, здесь будет NULL
. Если
MySQL выбирает неправильный индекс, Вы можете вынуждать MySQL использовать
другой индекс, используя myisamchk --analyze
. Подробности в
разделе "4.4.6.1 Синтаксис обращения
к myisamchk
". Можно применить и
USE INDEX/IGNORE INDEX
.
key_len
key_len
указывает длину ключа, который MySQL решил
использовать. Длина равна NULL
, если key
равен
NULL
. Обратите внимание, что это сообщает нам, сколько частей
составного ключа фактически использует MySQL.
ref
ref
показывает, которые столбцы или константы
используются с key
, чтобы выбрать строки из таблицы.
rows
rows
указывает число строк, которые MySQL должен
исследовать, чтобы выполнить запрос.
Extra
Distinct
Not exists
LEFT JOIN
на запросе и
не будет исследовать большее количество строк в этой таблице для предыдущей
комбинации строк после того, как найдет одну строку, которая соответствует
критериям LEFT JOIN
. Имеется пример этого:
SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;Считается, что
t2.id
определен как NOT NULL
.
В этом случае MySQL просмотрит t1
и будет искать строки в
t2
через t1.id
. Если MySQL находит строку
соответствий в t2
, он знает, что t2.id
никогда не
может быть NULL
, и не будет просматривать остальную часть строк
в t2
, которые имеют тот же самый идентификатор id
.
Другими словами, для каждой строки в t1
MySQL должен делать
только одиночную поисковую таблицу в t2
независимо от того,
сколько соответствий строк находится в t2
.
range checked for each record (index map: #)
Using filesort
join type
) и сохраняя ключ
сортировки+указатель на строку для всех строк, которые соответствуют
WHERE
. Затем ключи сортируются. В заключение строки будут
получены в сортируемом порядке.
Using index
Using temporary
ORDER BY
на наборе столбцов, отличном от того, который
был задан в предложении GROUP BY
.
Where used
WHERE
будет использоваться, чтобы ограничить то,
которые строки будут согласованы для следующей таблицы или посланы
пользователю. Если Вы не имеете эту информацию, и таблица имеет тип
ALL
или index
, Вы можете иметь что-то неправильное
в Вашем запросе (если Вы не предполагаете выбирать/исследовать все строки из
таблицы). Если Вы хотите получать ответы на Ваши запросы с такой скоростью, с
какой только возможно, Вы должны рассмотреть применение Using
filesort
и Using temporary
.Различные типы объединения перечислены ниже в порядке от лучших к худшим:
system
const
.
const
const
очень быстры, поскольку они доступны
для чтения только однажды!
eq_ref
const
. Это используется, когда все части индекса применяются
объединением, и индекс UNIQUE
или PRIMARY KEY
.
ref
ref
используется, если объединение использует только крайний
левый префикс ключа, или если ключ не UNIQUE
или PRIMARY
KEY
(другими словами, если объединение не может выбирать одиночную
строку, основанную на значении ключа).
range
key
указывает,
который индекс используется. Столбец key_len
содержит самую
длинную часть ключа, которая использовалась. Столбец ref
для этого типа будет NULL.
index
ALL
, за исключением того, что только индексное
дерево будет просмотрено. Это обычно быстрее, чем ALL
, поскольку
индексный файл обычно меньше, чем файл данных.
ALL
const
, и обычно
очень плохо во всех других случаях. Вы обычно можете
избежать ALL
, добавляя большее количество индексов, так, чтобы
строка могла быть найдена, основываясь на постоянных значениях или значениях
столбца более ранних таблиц.Вы можете получать хорошую индикацию относительно того, насколько хорошим
является объединение, умножая все значения в столбце rows
вывода
EXPLAIN
. Это должно сообщить Вам грубо, сколько строк MySQL
должен исследовать, чтобы выполнить запрос. Это число также используется,
когда Вы ограничиваете запросы переменной max_join_size
.
Подробности в разделе "5.5.2
Настройка параметров сервера".
Следующий пример показывает, как JOIN
может быть
оптимизирован, прогрессивно используя информацию, предоставляемую
EXPLAIN
.
Предположим, что Вы имеете инструкцию SELECT
, показанную
ниже, и что Вы исследуете ее, используя EXPLAIN
:
EXPLAIN SELECT tt.TicketNumber, tt.TimeIn, tt.ProjectReference, tt.EstimatedShipDate, tt.ActualShipDate, tt.ClientID, tt.ServiceCodes, tt.RepetitiveID, tt.CurrentProcess, tt.CurrentDPPerson, tt.RecordVolume, tt.DPPrinted, et.COUNTRY, et_1.COUNTRY, do.CUSTNAME FROM tt, et, et AS et_1, do WHERE tt.SubmitTime IS NULL AND tt.ActualPC = et.EMPLOYID AND tt.AssignedPC=et_1.EMPLOYID AND tt.ClientID = do.CUSTNMBR;
Например, предположим, что:
Таблица | Столбец | Тип столбца |
tt | ActualPC |
CHAR(10) |
tt | AssignedPC |
CHAR(10) |
tt | ClientID |
CHAR(10) |
et | EMPLOYID |
CHAR(15) |
do | CUSTNMBR |
CHAR(15) |
Таблица | Индекс |
tt | ActualPC |
tt | AssignedPC |
tt | ClientID |
et | EMPLOYID (первичный ключ) |
do | CUSTNMBR (первичный ключ) |
tt.ActualPC
распределены неравномерно.Первоначально, прежде, чем выполнились любые оптимизации, инструкция
EXPLAIN
производит следующую информацию:
table type possible_keys key key_len ref rows Extra et ALL PRIMARY NULL NULL NULL 74 do ALL PRIMARY NULL NULL NULL 2135 et_1 ALL PRIMARY NULL NULL NULL 74 tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872 range checked for each record (key map: 35)
Поскольку type
равен ALL
для каждой таблицы,
этот вывод указывает, что MySQL делает полное объединение для всех таблиц!
Это займет очень длительное время, поскольку большое число строк в каждой
таблице должно быть исследовано! Для нашего случая это
74*2135*74*3872=45268558720
строк. Если бы таблицы были больше,
Вы можете только воображать, как много времени потребуется.
Одна проблема здесь состоит в том, что MySQL не может использовать
индексы на столбцах эффективно, если они объявлены по-другому. В этом
контексте VARCHAR
и CHAR
то же самое, если они не
объявлены как различные длины. Потому, что tt.ActualPC
определен
как CHAR(10)
, а et.EMPLOYID
объявлен как
CHAR(15)
, имеется несоответствие длин.
Чтобы исправить это неравенство между длинами столбца, используйте
ALTER TABLE
, чтобы удлинить ActualPC
с 10 до 15:
mysql> ALTER TABLE tt MODIFY ActualPC VARCHAR(15);
Теперь tt.ActualPC
и et.EMPLOYID
равны
VARCHAR(15)
. Выполнение инструкции EXPLAIN
производит этот результат:
table type possible_keys key key_len ref rows Extra tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872 where used do ALL PRIMARY NULL NULL NULL 2135 range checked for each record (key map: 1) et_1 ALL PRIMARY NULL NULL NULL 74 range checked for each record (key map: 1) et eq_ref PRIMARY PRIMARY 15 tt.ActualPC 1
Это еще не совершенно, но намного лучше. Эта версия выполнена быстрее.
Второе исправление может быть сделано, чтобы устранить несоответствия длин
столбцов для сравнений tt.AssignedPC=et_1.EMPLOYID
и
tt.ClientID=do.CUSTNMBR
:
mysql> ALTER TABLE tt MODIFY AssignedPC VARCHAR(15), MODIFY ClientID VARCHAR(15);
Сейчас EXPLAIN
выведет следующее:
table type possible_keys key key_len ref rows Extra et ALL PRIMARY NULL NULL NULL 74 tt ref AssignedPC,ClientID,ActualPC ActualPC 15 et.EMPLOYID 52 where used et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1 do eq_ref PRIMARY PRIMARY 15 tt.ClientID 1
Это почти столь же хорошо, как это возможно вообще. Но все же еще недостаточно хорошо. Продолжим...
Остающаяся проблема состоит в том, что по умолчанию MySQL считает, что
значения в столбце tt.ActualPC
равномерно распределены, а это не
имеет место для таблицы tt
. Можно просто сообщить MySQL об этом:
shell> myisamchk --analyze PATH_TO_MYSQL_DATABASE/tt shell> mysqladmin refresh
Теперь объединение совершенно, и EXPLAIN
выведет такой отчет:
table type possible_keys key key_len ref rows Extra tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872 where used et eq_ref PRIMARY PRIMARY 15 tt.ActualPC 1 et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1 do eq_ref PRIMARY PRIMARY 15 tt.ClientID 1
Обратите внимание, что столбец rows
в выводе
EXPLAIN
представляет собой обучаемое предположение оптимизатора
объединения MySQL. Чтобы оптимизировать запрос, Вы должны проверить, являются
ли числа близкими к истине. Если это не так, Вы можете получить лучшую
эффективность, используя STRAIGHT_JOIN
в Вашей инструкции
SELECT
и пробуя внести в список таблицы в различном порядке в
предложении FROM
запроса.
В большинстве случаев Вы можете оценивать эффективность, считая дисковые
установки. Для маленьких таблиц Вы можете обычно находить строку за одну
дисковую установку (поскольку индекс, вероятно, кэшируется). Для больших
таблиц Вы можете оценивать (используя индексы дерева B++), что надо
log(число строк)/log(длина блока индекса/3*2/(длина индекса+длина
указателя данных))+1
установок, чтобы найти строку.
В MySQL блок индекса обычно равен 1024 байтам, а длина указателя данных
составляет 4 байта. 500000 строк с индексом длиной в 3 (medium integer)
обрабатываются за log(500000)/log(1024/3*2/(3+4))+1
=4.
Поскольку вышеупомянутый индекс требовал бы приблизительно 500000*7*3/2=5.2M (считается, что индексные буфера заполнены на 2/3, что является типичным), Вы будете, вероятно, иметь многое из индекса в памяти, и Вы будете, вероятно, нуждаться только в 1-2 обращениях, чтобы читать данные из OS, чтобы найти строку.
Для записи, однако, Вы будете нуждаться в 4 запросах установки (как показано выше), чтобы найти, где поместить новый индекс, и обычно в 2 установках, чтобы модифицировать индекс и записать строку данных.
Обратите внимание, что вышеупомянутое не означает, что Ваша прикладная программа будет требовать сложности N log N! Пока все кэшируется OS или SQL-сервером, работа будет идти только незначительно медленнее в то время, как таблица становится большей. После того, как данные становятся слишком большими, чтобы кэшироваться, работа будет идти намного медленнее, пока Ваши прикладные программы ограничены дисковыми установками (которые растут как N log N). Чтобы избежать этого, увеличьте индексный кэш, поскольку данные растут. Подробности в разделе "5.5.2 Настройка параметров сервера ".
SELECT
Вообще, когда Вы хотите сделать медленный SELECT ... WHERE
быстрее, первое, что подлежит проверке, можете или нет Вы добавить индекс.
Подробности в разделе "5.4.3 Как MySQL
использует индексы". Все ссылки между различными таблицами должны обычно
делаться с индексами. Вы можете использовать команду EXPLAIN
,
чтобы определить, которые индексы используются для SELECT
.
Подробности в разделе "5.2.1 Синтаксис
EXPLAIN
(получение информации о SELECT
)".
Некоторые общие советы:
myisamchk
--analyze
на таблице после того, как она была загружена релевантными
данными. Это модифицирует значение для каждой индексной части, которая
указывает среднее число строк, которые имеют то же самое значение. Для
уникальных индексов, это всегда 1, конечно. MySQL использует это, чтобы
решить, которые индексы выбрать, когда Вы подключаете две таблицы с
неконстантным выражением. Вы можете проверять результат из
analyze
выполнением SHOW INDEX FROM table_name
и
исследования столбца Cardinality
.
myisamchk --sort-index --sort-records=1
(если Вы хотите
сортировать на индексе 1). Если Вы имеете уникальный индекс, из которого Вы
хотите читать все записи, это хороший способ сделать процесс быстрее.
Обратите внимание, однако, что эта сортировка не написана оптимально и будет
брать довольно длительное время для большой таблицы!WHERE
Оптимизация WHERE
помещена в часть SELECT
потому,
что она обычно используется с SELECT
, но теми же самыми методами
оптимизируются инструкции DELETE
и UPDATE
.
Также обратите внимание, что этот раздел незавершен. MySQL делает много оптимизаций, и авторы пакета не имели времени, чтобы документировать их все.
Некоторые из оптимизаций, выполняемых MySQL перечислены ниже:
((a AND b) AND c OR (((a AND b) AND (c AND d)))) -> (a AND b AND c) OR (a AND b AND c AND d)
(a<b AND b=c) AND a=5 -> b>5 AND b=c AND a=5
(B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6) -> B=5 OR B=6
COUNT(*)
на одиночной таблице без WHERE
получен непосредственно из информации таблицы. Это также выполнено для любого
выражения NOT NULL
, когда используется только с одной таблицей.
SELECT
невозможны, и не
возвращает никаких строк.
HAVING
объединено с WHERE
, если Вы не
используете GROUP BY
или групповые функции
(COUNT()
, MIN()
...).
WHERE
будет создан,
чтобы получить быструю оценку WHERE
для каждого подобъединения,
а также пропускать все записи как можно скорее.
WHERE
на
индексе UNIQUE
или PRIMARY KEY
, где все индексные
части используются с постоянными выражениями и индексными частями, определена
как NOT NULL
.mysql> SELECT * FROM t WHERE primary_key=1; mysql> SELECT * FROM t1,t2 WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
ORDER BY
и в
GROUP BY
исходят из той же самой таблицы, то эта таблица
использована сначала при объединении.
ORDER BY
и отличное от него
предложение GROUP BY
, или если ORDER BY
или
GROUP BY
содержит столбцы из таблиц, иных, чем первая таблица в
очереди объединений, создается временная таблица.
SQL_SMALL_RESULT
, MySQL использует
временную таблицу в памяти.
HAVING
, будут пропущены.Некоторые примеры запросов, которые являются очень быстрыми:
mysql> SELECT COUNT(*) FROM tbl_name; mysql> SELECT MIN(key_part1),MAX(key_part1) FROM tbl_name; mysql> SELECT MAX(key_part2) FROM tbl_name WHERE key_part_1=constant; mysql> SELECT ... FROM tbl_name ORDER BY key_part1,key_part2,... LIMIT 10; mysql> SELECT ... FROM tbl_name ORDER BY key_part1 DESC,key_part2 DESC,... LIMIT 10;
Следующие запросы решены, используя только индексное дерево (все индексированные столбцы числовые):
mysql> SELECT key_part1,key_part2 FROM tbl_name WHERE key_part1=val; mysql> SELECT COUNT(*) FROM tbl_name WHERE key_part1=val1 AND key_part2=val2; mysql> SELECT key_part2 FROM tbl_name GROUP BY key_part1;
Следующие запросы применяют индексы, чтобы получить строки в сортируемом порядке без отдельного прохода сортировки:
mysql> SELECT ... FROM tbl_name ORDER BY key_part1,key_part2,... ; mysql> SELECT ... FROM tbl_name ORDER BY key_part1 DESC,key_part2 DESC,... ;
DISTINCT
DISTINCT
преобразован в GROUP BY
на всех
столбцах, DISTINCT
объединенный с ORDER BY
тоже
будет во многих случаях нуждаться во временной таблице.
При объединении LIMIT #
с DISTINCT
, MySQL
остановится, как только успешно найдет #
уникальных строк.
Если Вы не используете столбцы из всех применяемых таблиц, MySQL остановит просмотр неиспользуемых таблиц, как только найдет первое соответствие.
SELECT DISTINCT t1.a FROM t1,t2 where t1.a=t2.a;
В этом случае t1 используется прежде t2 (проверьте с помощью
EXPLAIN
), затем MySQL перестанет читать из t2 (для той
специфической строки в t1), когда первая строка в t2 будет найдена.
LEFT JOIN
и RIGHT JOIN
Действие A LEFT JOIN B
в MySQL выполнено следующим образом:
B
установлена, чтобы зависеть от таблицы
A
, и всех таблиц, которые зависят от A
.
A
, чтобы зависеть от всех таблиц за
исключением B
, которые используются в
условии LEFT JOIN
.
LEFT JOIN
перемещаются в WHERE
.
WHERE
выполнены.
A
, которая соответствует предложению
WHERE
, но не имеется никакой строки в B
, которая
соответствует условию LEFT JOIN
, то дополнительные строки
B
сгенерированы со всем набором столбцов в NULL
.
LEFT JOIN
, чтобы найти строки, которые
не существуют в некоторой таблице, и Вы имеете следующий тест:
column_name IS NULL
в части WHERE
, где column_name
представляет собой столбец, который объявлен как NOT NULL
, то
MySQL перестанет искать после большего количества строк (для специфической
комбинации ключа после того, как найдет одну строку, которая соответствует
условию LEFT JOIN
).RIGHT JOIN
реализован аналогично LEFT JOIN
.
Порядок чтения таблицы, принудительно заданный LEFT JOIN
и
STRAIGHT JOIN
, поможет оптимизатору объединения (который
вычисляет, в каком порядке таблицы должны быть соединены) сделать работу
намного быстрее, так как имеется меньшее количество перестановок таблицы,
которые надо проверить.
Обратите внимание, что вышеупомянутое означает, что, если Вы делаете запрос типа:
SELECT * FROM a,b LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key) WHERE b.key=d.key
MySQL будет делать полный просмотр b
, поскольку LEFT
JOIN
вынудит это читаться прежде, чем d
.
Исправление в этом случае должно изменить запрос на:
SELECT * FROM b,a LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key) WHERE b.key=d.key
LIMIT
В некоторых случаях MySQL обработает запрос по-другому, когда Вы
используете LIMIT #
и не используете HAVING
:
LIMIT
, MySQL
использует индексы в некоторых случаях, когда он обычно предпочел бы сделать
полный просмотр таблицы.
LIMIT #
в сочетании с ORDER
BY
, MySQL закончит сортировку, как только найдет первые #
строк вместо того, чтобы сортировать целую таблицу.
LIMIT #
с DISTINCT
MySQL
остановится, как только найдет #
уникальных строк.
GROUP BY
может быть решено, читая ключ
по порядку (или сортируя по ключу) с последующим вычислением результата до
изменений значения ключа. В этом случае LIMIT #
не будет
вычислять никакую ненужную операцию GROUP BY
.
#
строк пользователю, он
прервет текущий запрос.
LIMIT 0
будет всегда быстро возвращать пустой набор. Это
полезно, чтобы проверить запрос и получить типы столбцов результата.
LIMIT #
, чтобы вычислить,
сколько места необходимо, чтобы решить этот запрос.INSERT
Время, нужное, чтобы вставить запись, состоит приблизительно из:
Здесь числа пропорциональны полному времени. Это не учитывает время, нужное, чтобы открыть таблицы (это выполнено лишь однажды для каждого одновременно выполняемого запроса).
Размер таблицы замедляет вставку индексов на N log N (B-деревья).
Некоторые способы ускорить вставки:
INSERT
. Это намного быстрее, чем использование отдельных
инструкций INSERT
. Грамотная настройка переменной
myisam_bulk_insert_tree_size
может сделать это даже быстрее.
Подробности в разделе "4.5.5.4
Синтаксис SHOW VARIABLES
".
INSERT DELAYED
.
MyISAM
Вы можете вставлять строки
в то же самое время, когда работает SELECT
, если не имеется
никаких удаленных строк в таблицах.
LOAD DATA
INFILE
. Это примерно в 20 раз быстрее, чем использование
набора команд INSERT
.
LOAD DATA INFILE
, когда
таблица имеет много индексов. Используйте следующую процедуру:
CREATE TABLE
.
Например, при использовании mysql
или Perl-DBI.
FLUSH TABLES
или команду оболочки
mysqladmin flush-tables
.
myisamchk --keys-used=0 -rq /path/to/db/tbl_name
.
Это удалит все применяемые индексы из таблицы.
LOAD DATA INFILE
.
Это не будет модифицировать никакие индексы вообще и, следовательно, будет
работать очень быстро.
myisampack
, чтобы сделать ее еще меньше. Подробности в разделе
7.1.2.3 Характеристики сжатых таблиц
".
myisamchk -r -q
/path/to/db/tbl_name
. Это создаст индексное дерево в памяти перед
записью его на диск, что является намного быстрее потому, что это избегает
большого количества дисковых установок. Возникающее в результате индексное
дерево также совершенно сбалансировано.
FLUSH TABLES
или команду оболочки
mysqladmin flush-tables
.LOAD DATA INFILE
в некоторой
будущей версии MySQL. Начиная с MySQL 4.0, Вы также можете
использовать ALTER TABLE tbl_name DISABLE KEYS
вместо
myisamchk --keys-used=0 -rq /path/to/db/tbl_name
и
ALTER TABLE tbl_name ENABLE KEYS
вместо
myisamchk -r -q /path/to/db/tbl_name
. Этим путем Вы также
можете обойти шаг FLUSH TABLES
.
mysql> LOCK TABLES a WRITE; mysql> INSERT INTO a VALUES (1,23),(2,34),(4,33); mysql> INSERT INTO a VALUES (8,26),(6,29); mysql> UNLOCK TABLES;Основное различие в быстродействии в том, что буфер индексов сбрасывают на диск только однажды после того, как все инструкции
INSERT
завершили. Обычно имелось бы так много индексных буферных потоков, сколько
есть различных инструкций INSERT
. Блокировка не является
необходимой, если Вы можете вставлять все строки с одиночной инструкцией.
Блокировка будет также снижать общее время тестов с несколькими
подключениями, но максимальное время ожидания для некоторых потоков повысится
(потому, что они ждут блокировки). Например:
thread 1 does 1000 inserts thread 2, 3, and 4 does 1 insert thread 5 does 1000 insertsЕсли Вы не используете блокировку, 2, 3 и 4 закончаться перед 1 и 5. Если Вы используете блокировку, 2, 3 и 4, вероятно, не будут заканчиваться прежде, чем 1 или 5, но общее время должно быть приблизительно на 40% лучше. Так как операции
INSERT
, UPDATE
и DELETE
очень
быстры в MySQL, Вы получите лучшую полную эффективность, добавляя блокировки
вокруг всего, что делает больше, чем приблизительно 5 вставок или модификаций
в строке. Если Вы делаете очень много вставок в строке, Вы могли бы делать
LOCK TABLES
, сопровождаемые UNLOCK TABLES
время от
времени (примерно каждые 1000 строк), чтобы позволить другим потокам доступ к
таблице. Конечно же, LOAD DATA INFILE
все равно намного быстрее
для загрузки данных.Чтобы дополнительно получить несколько большее быстродействие для операций
LOAD DATA INFILE
и INSERT
, увеличьте буфер ключа.
Подробности в разделе "5.5.2
Настройка параметров сервера".
UPDATE
Запросы модификации оптимизированы как запрос SELECT
.
Быстродействие дополнительной записи зависит от размера данных, которые
изменяются, и числа индексов, в которые вносятся поправки. Индексы, которые
не изменены, не будет модифицироваться.
Также, другой способ получать быстрые модификации состоит в том, чтобы задержать модификации, а затем сделать много модификаций в строке позже. Выполнение многих модификаций в строке намного более быстрое, чем выполнение их по одной, если Вы блокируете таблицу.
Обратите внимание, что, при работе с динамическим форматом записи
модификация записи на более длинную может привести к разделению ее на
фрагменты. Так что, если Вы делаете это часто, очень важно иногда вызывать
OPTIMIZE TABLE
. Подробности в разделе
"4.5.1 Синтаксис OPTIMIZE TABLE
".
DELETE
Если надо удалить все строки из таблицы, примените вызов
TRUNCATE TABLE table_name
.
Время, нужное, чтобы удалить запись, точно пропорционально числу индексов. Чтобы удалять записи быстрее, Вы можете увеличивать размер индексного кэша. Подробности в разделе "5.5.2 Настройка параметров сервера".
thread_cache_size
. Подробности в разделе
"5.5.2 Настройка параметров сервера
".
EXPLAIN
. Подробности в разделе
"5.2.1 Синтаксис EXPLAIN
(получение информации о SELECT
)".
SELECT
на таблицах, которые часто
модифицируются. Это должно помочь избежать проблем с блокировкой таблицы.
MyISAM
могут вставлять строки в таблицу без
удаленных строк в то же самое время, когда другой запрос ведет чтение. Если
это важно для Вас, Вы должны рассмотреть методы, где Вы не должны удалить
строки или выполните OPTIMIZE TABLE
после того, как Вы удалили
много строк сразу.
ALTER TABLE ... ORDER BY expr1,expr2...
если Вы обычно получаете строки в порядке expr1,expr2,... . Используя эту
опцию после внесения больших изменений для таблицы, Вы можете получить
значительно более высокую эффективность.
SELECT * FROM table_name WHERE hash=MD5(concat(col1,col2)) AND
col_1='constant' AND col_2='constant'
VARCHAR
или BLOB
. Вы получите
динамическую длину строки, как только Вы используете хоть один стобец
VARCHAR
или BLOB
. Подробности в разделе
"7 Типы таблиц MySQL".
UPDATE table set count=count+1 where
index_column=constant
очень быстрая! Это действительно важно, когда Вы
используете базы данных подобные MySQL, которые имеют только блокировку
уровня таблицы. Это также даст лучшую эффективность с большинством баз
данных, поскольку администратор блокировки строки в этом случае будет иметь
куда меньше работы.
INSERT /*! DELAYED */
, если Вы не должны знать,
когда Ваши данные будут записаны. Это ускоряет дела потому, что много записей
могут быть выполнены за один дисковый обмен.
INSERT /*! LOW_PRIORITY */
, когда Вы хотите,
чтобы Ваши вызовы select были более важными.
SELECT /*! HIGH_PRIORITY */
, чтобы получить
select, обходящий очередь. То есть select будет выполнен, даже если имеется
кто-то ждущий, чтобы сделать запись в таблицу.
INSERT
, чтобы сохранить
много строк одной командой SQL (многие серверы SQL поддерживают это).
LOAD DATA INFILE
, чтобы загрузить большие
количества данных. Это быстрее, чем нормальные вставки, а будет еще быстрее,
когда myisamchk
интегрирован в mysqld
.
AUTO_INCREMENT
, чтобы
сделать уникальные значения.
OPTIMIZE TABLE
время от времени, чтобы избежать
фрагментации при использовании динамического формата таблицы. Подробности в
разделе "4.5.1
Синтаксис OPTIMIZE TABLE
".
HEAP
, чтобы получить большее
быстродействие, когда это возможно. Подробности в разделе
"7 Типы таблиц MySQL".
name
вместо customer_name
в таблице
заказчиков). Чтобы сделать Ваши имена переносными на другие SQL-серверы, Вы
должны озаботиться тем, чтобы они не превышали в длину 18 символов.
MyISAM
непосредственно, Вы могли бы получить увеличение быстродействия в 2-5 раз в
сравнении с использованием интерфейса SQL. Чтобы сделать это, данные должны
быть на том же самом сервере, что и прикладная программа, и обычно к ним
можно обратиться только одним процессом (потому, что внешняя блокировка файла
работает очень медленно). Можно было устранить вышеупомянутые проблемы,
представляя команды MyISAM
низкого уровня в сервере MySQL (это
могло бы быть одним простым способом получить большее количество
эффективности, если необходимо).
DELAY_KEY_WRITE=1
будет делать
модифицирование индексов быстрее, поскольку они не регистрируются на диске,
пока файл не закрыт. Обратная сторона в том, что Вы должны выполнить
myisamchk
на этих таблицах прежде, чем Вы запускаете
mysqld
, чтобы гарантировать, что они правильные, если что-то
уничтожило mysqld
в середине запроса. Поскольку информация ключа
может всегда генерироваться из данных, Вы не должны терять что-нибудь,
используя DELAY_KEY_WRITE
.Вы можете найти обсуждение различных методов блокировки в приложении. Подробности в разделе "6.4 Методы для блокировки".
Вся блокировка в MySQL свободна от тупика. Она управляется, всегда запрашивая все необходимые блокировки сразу в начале запроса и всегда блокируя таблицы в том же самом порядке.
Метод блокировки MySQL, использованный для операции WRITE
,
работает следующим образом:
Метод блокировки MySQL, использованный для операции READ
,
работает следующим образом:
Когда блокировка освобождается, она становится доступной потокам в очереди блокировок записи, а после них потокам в очереди блокировок чтения.
Это означает, что, если Вы имеете много модификаций на таблице, инструкции
SELECT
будут ждать до окончания всех модификаций.
Чтобы обойти это для случая, где Вы хотите делать много операций
INSERT
и SELECT
на таблице, Вы можете вставлять
строки во временную таблицу и периодически модифицировать реальную таблицу
записями из временной таблицы.
Это может быть выполнено кодом:
mysql> LOCK TABLES real_table WRITE, insert_table WRITE; mysql> insert into real_table select * from insert_table; mysql> TRUNCATE TABLE insert_table; mysql> UNLOCK TABLES;
Вы можете использовать параметр LOW_PRIORITY
с инструкциями
INSERT
, UPDATE
или DELETE
, а
HIGH_PRIORITY
только с SELECT
, если Вы хотите
располагать по приоритетам поиск в некоторых специфических случаях. Вы можете
также запустить mysqld
с параметром
--low-priority-updates
, чтобы получить тот же самое поведение.
Использование SQL_BUFFER_RESULT
может также сделать
блокировку таблицы короче.
Вы могли бы также изменять код блокировки в mysys/thr_lock.c, чтобы использовать одиночную очередь. В этом случае блокировки записи и чтения имели бы тот же самый приоритет, что может помочь некоторым программам.
Код блокировки таблиц в MySQL свободен от тупиков.
MySQL использует блокировку таблицы (вместо блокировки строки или столбца)
на всех типах таблицы, за исключением BDB
, чтобы достичь очень
высокого быстродействия блокировки. Для больших таблиц блокировка таблицы
НАМНОГО лучше, чем блокировка строки для большинства прикладных программ, но
имеются, конечно, некоторые ловушки.
Для таблиц типов BDB
и InnoDB
MySQL использует
блокировку таблицы только, если Вы скомандовали LOCK TABLES
или
выполняете команду, которая изменит каждую строку в таблице подобно
ALTER TABLE
. Для этих типов таблицы я рекомендую Вам не
использовать LOCK TABLES
вообще.
В MySQL Version 3.23.7 и выше Вы можете вставлять строки в таблицы типа
MyISAM
в то же самое время, когда другие потоки читают из
таблицы. Обратите внимание, что в настоящее время это работает только, если
не имеется никаких отверстий после удаленных строк в таблице во время
вставки. Когда все отверстия будут заполнены новыми данными, параллельные
вставки снова будут допускаться автоматически.
Блокировка таблицы дает возможность многим потокам читать из таблицы в то же самое время, но если поток хочет писать в таблицу, он должен сначала получить исключительный доступ. В течение модификации все другие потоки, которые хотят обращаться к этой специфической таблице, будут ждать, пока модификация не завершится.
Поскольку модификации на таблицах обычно являются более важными, чем
SELECT
, все инструкции, которые модифицируют таблицу, имеют
более высокий приоритет, чем те инструкции, которые получают информацию из
таблицы. Вы можете изменять это, используя LOW_PRIORITY
с
инструкцией, которая делает модификацию, или HIGH_PRIORITY
с
SELECT
).
Начиная с MySQL Version 3.23.7, можно использовать переменную
max_write_lock_count
, чтобы заставить MySQL временно дать всем
инструкциям SELECT
, которые ждут таблицу, более высокий
приоритет после специфического числа вставок на таблице.
Блокировка таблицы, однако, не очень хороша в следующих случаях:
SELECT
, который берет длительное
время, чтобы выполниться.
UPDATE
на используемой
таблице. Этот клиент будет ждать, пока SELECT
не закончится.
SELECT
относительно той же самой таблицы. Поскольку UPDATE
имеет более
высокий приоритет, чем SELECT
, этот SELECT
будет
ждать UPDATE
, чтобы закончиться. Это будет также ждать, когда
закончится первый SELECT
!
full disk
, когда все потоки,
которые хотят обращаться к прикладной таблице, будут также помещены в
состояние ожидания до тех пор, пока большее количество дискового пространства
не станет доступно.Некоторые решения для этой проблемы:
SELECT
. Вам,
вероятно, придется создавать некоторые итоговые таблицы, чтобы сделать это.
mysqld
с опцией
--low-priority-updates
. Это даст всем инструкциям, которые
модифицируют таблицу, более низкий приоритет, чем инструкции
SELECT
. В этом случае последняя инструкция SELECT
в
предыдущем сценарии выполнилась бы перед инструкцией INSERT
.
INSERT
,
UPDATE
или DELETE
с более низким приоритетом,
указав атрибут LOW_PRIORITY
.
mysqld
с низким значением для
max_write_lock_count, чтобы дать блокировки
READ
после того, как отработает некоторое число блокировок
WRITE
.
SET SQL_LOW_PRIORITY_UPDATES=1
. Подробности в разделе
"5.5.6 Синтаксис SET
".
SELECT
очень важен с
помощью атрибута HIGH_PRIORITY
.
INSERT
, объединенной с
SELECT
, переключитесь, чтобы использовать новые таблицы типа
MyISAM
, поскольку они поддерживают параллельную работу вызовов
SELECT
и INSERT
.
INSERT
и
SELECT
, атрибут DELAYED
в вызове
INSERT
, вероятно, решит Ваши проблемы.
SELECT
и DELETE
,
опция LIMIT
в инструкции DELETE
может помочь.MySQL хранит данные строк и индексные данные в отдельных файлах. Многие (почти все) другие базы данных смешивают строки и индексные данные в том же самом файле. Я полагаю, что выбор MySQL лучше для очень широкого диапазона современных систем.
Другой способ сохранять данные строк состоит в том, чтобы хранить информацию для каждого столбца в отдельной области (примеры: SDBM и Focus). Это вызовет падение эффективности для каждого запроса, который обращается больше, чем к одному столбцу. Эта модель далеко не хороша для построения универсальных баз данных.
Более общий случай: индекс и данные сохранены вместе (подобно Oracle/Sybase). В этом случае Вы найдете информацию строк в листе страниц индекса. Хорошо с этим размещением то, что во многих случаях, в зависимости от того, как хорошо индекс кэшируется, экономится медленное дисковое чтение. Плохо с этим размещением то, что:
Одна из наиболее распространенных оптимизаций должна получить Ваши данные и индексы, чтобы брать так мало места на диске, насколько возможно. Это может давать огромные улучшения потому, что диск читается меньше, и оперативная память экономится. Индексация также берет меньшее количество ресурсов, если выполнена на меньших столбцах.
MySQL поддерживает много различных типов таблиц и форматов строк. Выбор правильного формата таблицы может давать Вам большое усиление эффективности. Подробности в разделе "7 Типы таблиц MySQL ".
Вы можете получать лучшую эффективность на таблице и минимизировать "складские площади" на диске, используя методы, перечисленные ниже:
MEDIUMINT
часто бывает куда лучше,
чем INT
в чистом виде.
NOT NULL
, если это возможно. Это
сделает все быстрее, и Вы сэкономите один бит на столбец. Обратите внимание,
что, если Вы действительно нуждаетесь в NULL
в Вашей прикладной
программе, Вы должны определенно использовать это. Только не стоит иметь это
свойство заданным на всех столбцах по умолчанию.
VARCHAR
,
TEXT
или BLOB
), используется формат записи
фиксированного размера. Это быстрее, но, к сожалению, может тратить впустую
некоторое место. Подробности в разделе
"7.1.2 Форматы таблиц MyISAM".
Индексы используются, чтобы быстро найти строки со специфическим значением одного столбца. Без индекса MySQL должен начать с первой записи и затем пролистывать целую таблицу, пока не найдет релевантные строки. Если таблица имеет индекс для рассматриваемых столбцов, MySQL может быстро получить позицию, чтобы позиционироваться на середину файла данных без того, чтобы иметь необходимость рассматривать все данные. Если таблица имеет 1000 строк, это по крайней мере в 100 раз быстрее, чем последовательное чтение. Обратите внимание, что если Вы должны обратиться почти ко всем 1000 строкам, быстрее читать файл последовательно потому, что мы сэкономим дисковые установки.
Все индексы в MySQL (PRIMARY
, UNIQUE
и
INDEX
) сохранены в B-деревьях. Строки автоматически сжимаются с
использованием конечных пробелов и префикса.
Индексы используются для:
WHERE
.
MAX()
или MIN()
для
специфического индексированного столбца. Это оптимизировано препроцессором,
который проверяет, используете ли Вы WHERE
key_part_#=constant
на всех частях ключа <N. В этом случае MySQL будет делать одиночный поиск
ключа и заменит MIN()
выражением с константой. Если все
выражения заменятся на константы, запрос возвратится сразу:
SELECT MIN(key_part2),MAX(key_part2) FROM table_name where key_part1=10
ORDER BY key_part_1,key_part_2
). Ключ читается в
обратном порядке, если все части ключа сопровождаются словом
DESC
. Индекс может также использоваться, даже если ORDER
BY
не соответствует индексу точно, пока все неиспользуемые индексные
части и все дополнительные столбцы в ORDER BY
представляют собой
константы в предложении WHERE
. Следующие запросы используют
индекс, чтобы решить часть ORDER BY
:
SELECT * FROM foo ORDER BY key_part1,key_part2,key_part3; SELECT * FROM foo WHERE column=constant ORDER BY column, key_part1; SELECT * FROM foo WHERE key_part1=const GROUP BY key_part2;
SELECT key_part3 FROM table_name WHERE key_part1=1
Предположим, что Вы выдаете следующую инструкцию SELECT
:
mysql> SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;
Если многостолбиковый индекс существует на col1
и
col2
, соответствующие строки могут быть выбраны непосредственно.
Если отдельные индексы с одним столбцом существуют на col1
и
col2
, оптимизатор пробует находить наиболее ограничительный
индекс, решая, который индекс найдет меньшее количество строк, и используя
этот индекс, чтобы выбрать строки.
Если таблица имеет многостолбиковый индекс, любой крайний левый префикс
индекса может использоваться оптимизатором, чтобы найти строки. Например,
если Вы имеете индекс с тремя столбцами на (col1,col2,col3)
, Вы
индексировали возможности поиска на (col1)
,
(col1,col2)
и (col1,col2,col3)
.
MySQL не может использовать частичный индекс, если столбцы не формируют
крайний левый префикс из индекса. Предположим, что Вы имеете инструкции
SELECT
, показанные ниже:
mysql> SELECT * FROM tbl_name WHERE col1=val1; mysql> SELECT * FROM tbl_name WHERE col2=val2; mysql> SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;
Если индекс существует на (col1,col2,col3)
, только первый
запрос, показанный выше, использует индекс. Второй и третий запросы включают
индексированные столбцы, но (col2)
и (col2,col3)
не крайние левые префиксы для (col1,col2,col3)
.
MySQL также использует индексы для сравнений
LIKE
, если параметр для LIKE
представляет собой
строку-константу, которая не начинается с группового символа. Например,
следующие инструкции SELECT
используют индексы:
mysql> select * from tbl_name where key_col LIKE "Patrick%"; mysql> select * from tbl_name where key_col LIKE "Pat%_ck%";
В первой инструкции только строки с "Patrick" <=key_col <
"Patricl"
рассматриваются. Во второй инструкции будут обработаны
только строки с "Pat" <=key_col < "Pau"
.
Следующие инструкции SELECT
не будут использовать индексы:
mysql> select * from tbl_name where key_col LIKE "%Patrick%"; mysql> select * from tbl_name where key_col LIKE other_col;
В первой инструкции значение LIKE
начинается с группового
символа. Во второй инструкции значение LIKE
не константа.
Поиск, использующий
column_name IS NULL
, применяет индексы, если column_name
представляет собой индекс.
MySQL обычно использует индекс, который находит наименьшее число строк.
Индекс используется для столбцов, которые Вы сравниваете следующими
операторами: =
, >
, >=
,
<
, <=
, BETWEEN
и
LIKE
с префиксом, представляющим собой не групповой символ,
например, допустимо something%
.
Любой индекс, который не охватывает все уровни AND
в
предложении WHERE
, не используется, чтобы оптимизировать запрос.
Другими словами: чтобы быть способным использовать индекс, префикс индекса
должен использоваться в каждом AND
в группе.
Следующие предложения WHERE
используют индексы:
... WHERE index_part1=1 AND index_part2=2 AND other_column=3 ... WHERE index=1 OR A=10 AND index=2 /* index = 1 OR index = 2 */ ... WHERE index_part1='hello' AND index_part_3=5 /* optimized like "index_part1='hello'" */ ... WHERE index1=1 and index2=2 or index1=3 and index3=3; /* Can use index on index1 but not on index2 or index 3 */
Эти предложения WHERE
НЕ используют индексы:
... WHERE index_part2=1 AND index_part3=2 /* index_part_1 is not used */ ... WHERE index=1 OR A=10 /* Index is not used in both AND parts */ ... WHERE index_part1=1 OR index_part2=10 /* No index spans all rows */
Обратите внимание, что в некоторых случаях MySQL все равно не будет использовать индекс, даже если можно было бы это сделать. Это связано с особенностями логики СУБД. Некоторые из таких случаев:
LIMIT
,
чтобы получить только часть строк, MySQL использует индекс в любом случае,
поскольку может намного быстрее найти строки, возвращаемые в результате.Все типы столбцов MySQL могут быть индексированы. Использование индексов
на релевантных столбцах представляет собой самый лучший способ улучшить
эффективность операций SELECT
.
Максимальное число ключей и максимальная длина индекса определены в драйвере таблицы. Подробности в разделе "7 Типы таблиц MySQL". Вы можете со всеми драйверами таблицы иметь по крайней мере 16 ключей и общую индексную длину по крайней мере в 256 байт.
Для столбцов типов CHAR
и VARCHAR
Вы можете
индексировать префикс столбца. Это намного быстрее и требует меньшего
количества дискового пространства, чем индексация целого столбца. Синтаксис,
который надо использовать в инструкции CREATE TABLE
, чтобы
индексировать префикс для столбца, выглядит следующим образом:
KEY index_name (col_name(length))
Пример ниже создает индекс первых 10 символов столбца name
:
mysql> CREATE TABLE test (name CHAR(200) NOT NULL, KEY index_name (name(10)));
Для столбцов BLOB
и TEXT
Вы должны индексировать
именно префикс столбца. Там Вы не можете индексировать весь столбец.
В MySQL Version 3.23.23 или позже Вы можете также создавать специальные
индексы FULLTEXT. Они используются для полнотекстового
поиска. Только тип таблицы MyISAM
поддерживает индексы
FULLTEXT
. Они могут быть созданы только из столбцов
VARCHAR
и TEXT
. Индексация всегда выполняется над
всем столбцом, частичная индексация пока не поддержана.
MySQL может создавать индексы на нескольких столбцах. Индекс может
включать до 15 столбцов. На столбцах типов CHAR
и
VARCHAR
Вы можете использовать префикс столбца как часть индекса.
MySQL использует индексы на нескольких столбцах таким способом, что
запросы становятся более быстрыми, когда Вы определяете известное количество
данных для первого столбца индекса в предложении WHERE
, даже
если Вы не определяете значения для других столбцов вообще.
Предположим, что таблица создана, используя следующую спецификацию:
mysql> CREATE TABLE test (id INT NOT NULL, last_name CHAR(30) NOT NULL, first_name CHAR(30) NOT NULL, PRIMARY KEY (id), INDEX name (last_name,first_name));
Индекс name
охватывает столбцы last_name
и
first_name
. Индекс будет использоваться для запросов, которые
определяют значения в известном диапазоне для last_name
или для
last_name
и first_name
вместе. Следовательно,
индекс name
будет использоваться для следующих запросов:
mysql> SELECT * FROM test WHERE last_name="Widenius"; mysql> SELECT * FROM test WHERE last_name="Widenius" AND first_name="Michael"; mysql> SELECT * FROM test WHERE last_name="Widenius" AND (first_name="Michael" OR first_name="Monty"); mysql> SELECT * FROM test WHERE last_name="Widenius" AND first_name >="M" AND first_name < "N";
Однако, индекс name
НЕ будет использоваться в запросах:
mysql> SELECT * FROM test WHERE first_name="Michael"; mysql> SELECT * FROM test WHERE last_name="Widenius" OR first_name="Michael";
За подробностями по улучшению работы с индексами в MySQL отсылаю Вас к разделу "5.4.3 Как MySQL использует индексы".
Переменные table_cache
, max_connections
и
max_tmp_tables
воздействуют на максимальное число файлов,
которые сервер хранит открытыми. Если Вы увеличиваете одно из них, Вы можете
нарваться на ограничение, наложенное Вашей операционной системой на число
описателей открытого файла на процесс. Однако, Вы можете обойти ограничение
многих систем. Консультируйтесь с Вашей документацией на OS, чтобы выяснить,
как это сделать потому, что методы для изменения ограничения везде свои.
Переменная table_cache
связана с max_connections
.
Например, для 200 параллельных подключений, Вы должны иметь кэш таблицы по
крайней мере 200*n
, где n
максимальное число таблиц
в объединении. Вы также должны резервировать некоторые описатели файла
дополнительно для временных таблиц и файлов.
Кэш открытых таблиц может расти до максимума, заданного
table_cache
(значение по умолчанию 64, это может быть изменено с
помощью опции -O table_cache=#
при вызове сервера
mysqld
). Таблица никогда не будет закрыта за исключением того
случая, когда кэш заполняется, а другой поток пробует открыть таблицу, или
если Вы используете команду mysqladmin refresh
или
mysqladmin flush-tables
.
Когда кэш таблицы заполняется, сервер использует следующую процедуру, чтобы найти запись кэша, которую надо использовать:
Таблица открыта для каждого параллельного доступа. Это означает, что, если
Вы имеете два потока, обращающиеся к той же самой таблице, или обращаетесь к
таблице дважды в том же самом запросе (через AS
), таблица должна
быть открыта дважды. Первое открытие любой таблицы берет два описателя файла,
каждое дополнительное использование таблицы берет только один описатель
файла. Лишний описатель для первого открытия используется для индексного
файла: этот описатель разделен между всеми потоками.
Вы можете проверять, является ли Ваш кэш таблицы слишком маленьким,
проверяя переменную opened_tables
в mysqld
. Если
это значение очень большое, даже если Вы не делали много вызовов
FLUSH TABLES
, Вы должны увеличить Ваш кэш таблицы. Подробности в
разделе "4.5.5.3 SHOW STATUS
".
Если Вы имеете много файлов в каталоге, операции открытия, закрытия и
создания будут медленными. Если Вы выполняете инструкции SELECT
относительно многих различных таблиц, будет иметься некоторое замедление,
когда кэш таблицы заполнится потому, что для каждой таблицы, которая должна
быть открыта, другая закроется. Вы можете уменьшить задержку, делая больше
кэш для таблиц.
Когда Вы выполняете mysqladmin status
, Вы будете видеть нечто
вроде этого вывода:
Uptime: 426 Running threads: 1 Questions: 11082 Reloads: 1 Open tables: 12
Это может несколько озадачить, если Вы имеете только 6 таблиц.
MySQL представляет собой многопоточное приложение, так что он может иметь много запросов к той же самой таблице одновременно. Чтобы минимизировать проблему с двумя потоками, имеющими различные состояния на том же самом файле, таблица будет открыта независимо каждым параллельным потоком. Это берет некоторую дополнительную память и один описатель файла для файла данных. Описатель индексного файла разделен между всеми потоками.
Начнем обзор с уровня системы, так как некоторые из этих решений должны быть сделаны очень рано. В других случаях рассмотрение будет не очень глубоким потому, что не сможет сильно повлиять на результаты. Однако, всегда хорошо иметь представление относительно того, сколько можно извлечь пользы, меняя настройки на этом уровне.
Используемая OS очень важна! Чтобы с толком использовать многопроцессорные системы, нужно применять Solaris (потому, что потоки там работают очень хорошо) или Linux (потому, что ядро 2.2 имеет очень приличную поддержку SMP). Также на 32-разрядных машинах Linux имеет ограничение в 2G для размера файла по умолчанию. Но это исправлено в файловых системах XFS/Reiserfs. Если Вы имеете потребность в файлах больше, чем 2G, на Linux-intel 32 bit, Вы должны получить заплату LFS для файловой системы ext2.
Другие советы и предупреждения:
--skip-locking
в MySQL, чтобы избежать
внешней блокировки. Обратите внимание, что это не будет воздействовать на
функциональные возможности MySQL, пока Вы выполняете только один сервер.
Только не забудьте завершить сервер (или блокировать релевантные части)
прежде, чем Вы выполните myisamchk
. На некоторых системах эта
опция обязательна потому, что внешняя блокировка не работает в любом случае.
Опция --skip-locking
по умолчанию включена при компиляции с
MIT-pthreads потому, что flock()
не полностью поддержан
MIT-pthreads на всех платформах. Это также значение по умолчанию для Linux,
поскольку блокировка файлов в Linux еще не безопасна. Единственный случай,
когда Вы не можете использовать --skip-locking
: если Вы
выполняете много серверов MySQL (не клиентов) на тех же самых данных или
выполняете myisamchk
на таблице без предварительной блокировки
сервера и сброса таблиц на диск. Вы можете применять
LOCK TABLES
/UNLOCK TABLES
, даже если Вы используете
опцию --skip-locking
Вы можете получать заданные по умолчанию буферные размеры, используемые
сервером mysqld
, этой командой:
shell> mysqld --help
Эта команда производит список всех параметров mysqld
и
переменных с перестраиваемой конфигурацией. Вывод включает значения по
умолчанию и выглядит так:
Possible variables for option --set-variable (-O) are: back_log current value: 5 bdb_cache_size current value: 1048540 binlog_cache_size current_value: 32768 connect_timeout current value: 5 delayed_insert_timeout current value: 300 delayed_insert_limit current value: 100 delayed_queue_size current value: 1000 flush_time current value: 0 interactive_timeout current value: 28800 join_buffer_size current value: 131072 key_buffer_size current value: 1048540 lower_case_table_names current value: 0 long_query_time current value: 10 max_allowed_packet current value: 1048576 max_binlog_cache_size current_value: 4294967295 max_connections current value: 100 max_connect_errors current value: 10 max_delayed_threads current value: 20 max_heap_table_size current value: 16777216 max_join_size current value: 4294967295 max_sort_length current value: 1024 max_tmp_tables current value: 32 max_write_lock_count current value: 4294967295 myisam_sort_buffer_size current value: 8388608 net_buffer_length current value: 16384 net_retry_count current value: 10 net_read_timeout current value: 30 net_write_timeout current value: 60 query_buffer_size current value: 0 record_buffer current value: 131072 record_rnd_buffer current value: 131072 slow_launch_time current value: 2 sort_buffer current value: 2097116 table_cache current value: 64 thread_concurrency current value: 10 tmp_table_size current value: 1048576 thread_stack current value: 131072 wait_timeout current value: 28800
Если имеется работающий сервер mysqld
, Вы можете увидеть,
какие значения он фактически использует для переменных, выполняя эту команду:
shell> mysqladmin variables
Вы можете находить полное описание для всех переменных в разделе
"4.5.5.4 SHOW VARIABLES
".
Вы можете также видеть некоторую статистику с сервера, выдавая команду
SHOW STATUS
. Подробности в разделе
"4.5.5.3 SHOW STATUS
".
MySQL использует алгоритмы, которые являются очень хорошо масштабируемыми, так что Вы обычно можете работать с очень небольшой памятью. Если Вы даете MySQL больше памяти, Вы обычно будете получать лучшую эффективность.
При настройке сервера MySQL есть две наиболее важных переменных:
key_buffer_size
и table_cache
.
Если Вы имеете много памяти (>=256M) и много таблиц и хотите получить максимальную эффективность с умеренным числом клиентов, Вы должны использовать нечто подобное этому:
shell> safe_mysqld -O key_buffer=64M -O table_cache=256 \ -O sort_buffer=4M -O record_buffer=1M &
Если Вы имеете только 128M и всего несколько таблиц, но Вы делаете много сортировок, Вы можете использовать нечто, подобно этому:
shell> safe_mysqld -O key_buffer=16M -O sort_buffer=1M
Если Вы имеете небольшую память и большое количество подключений, используйте следующее решение:
shell> safe_mysqld -O key_buffer=512k -O sort_buffer=100k \ -O record_buffer=100k &
Или вот это:
shell> safe_mysqld -O key_buffer=512k -O sort_buffer=16k \ -O table_cache=32 -O record_buffer=8k \ -O net_buffer=1K &
Если Вы делаете GROUP BY
или ORDER BY
на файлах,
которые являются намного больше, чем Ваша доступная память, Вы должны
увеличить значение record_rnd_buffer
, чтобы ускорить чтение
строк после того, как сортировка будет выполнена.
Когда Вы установили MySQL, каталог support-files будет хранить
некоторые различные файлы примера my.cnf
, например,
my-huge.cnf, my-large.cnf, my-medium.cnf и
my-small.cnf, которые Вы можете использовать как основу, чтобы
оптимизировать Вашу систему.
Если имеется очень много подключений, может происходить ``swapping
problem'', если mysqld
не был конфигурирован, чтобы использовать
очень небольшую память для каждого подключения. Конечно, mysqld
работает много лучше, если Вы имеете достаточно памяти для всех подключений.
Обратите внимание, что, если Вы изменяете опцию mysqld
, это
остается в силе только для этого образца станции.
Чтобы увидеть эффект от изменения параметра, сделайте:
shell> mysqld -O key_buffer=32m --help
Удостоверьтесь, что опция --help
последняя; иначе эффект
любых перечисленных на командной строке после нее параметров не будет
отражен в выводе.
Большинство следующих тестов выполнено на Linux с эталонными тестами MySQL, но они должны дать некоторые данные для других операционных систем и рабочих нагрузок системы.
Вы получаете самую быструю выполнимую программу, когда Вы компонуете ее с
опцией времени компоновки -static
.
В Linux Вы получите самый быстрый код при компиляции с pgcc
и опцией -O3
. Чтобы откомпилировать sql_yacc.cc с этими
параметрами, Вы нуждаетесь примерно в 200M памяти потому, что
gcc/pgcc
требует много памяти, чтобы сделать все функции
встроенными. Вы должны также установить CXX=gcc
при
конфигурировании MySQL, чтобы избежать включения библиотеки
libstdc++
. Обратите внимание, что при работе с некоторыми
версиями pgcc
возникающий в результате код выполнится только на
истинных процессорах Pentium, даже если Вы используете опцию транслятора,
чтобы возникающий в результате код работал на всех процессорах типа x586.
Только используя лучший транслятор и/или лучшие параметры транслятора, Вы уже можете получить увеличение быстродействия Вашей прикладной программы на 10-30%! Это особенно важно, если Вы компилируете SQL-сервер сами.
Авторы пакета проверили компиляторы Cygnus CodeFusion и Fujitsu, но на момент этого тестирования они были недостаточно свободны от ошибок, чтобы позволить MySQL компилироваться с включенной оптимизацией.
Когда Вы компилируете MySQL, Вы должны включить поддержку только для тех
наборов символов, которые Вы собираетесь использовать (опция
--with-charset=xxx
). Стандартные двоичные дистрибутивы MySQL
компилируются с поддержкой всех наборов символов.
Имеется список некоторых измерений, которые сделали авторы пакета:
pgcc
и компилируете все с опцией
-O6
, сервер mysqld
на 1% быстрее, чем с
gcc
2.95.2.
-static
), результат на
14% медленнее в Linux. Обратите внимание, что Вы все еще можете использовать
динамическую библиотеку MySQL. Это критично только для сервера.
mysqld
командой strip
libexec/mysqld
, возникающий в результате двоичный код может
быть до 4% быстрее.
localhost
, MySQL по умолчанию использует именно сокеты.
--with-debug=full
, теряете 20%
скорости для большинства запросов, но некоторые запросы могут еще более
замедлиться (эталонные тесты до 36%). Если Вы используете
--with-debug
, потери составят около 15%. Запуская
mysqld
, скомпилированный с опцией
--with-debug=full
, с --skip-safemalloc
конечный
результат должен быть близок к варианту --with-debug
.
gcc
2.95.2.
gcc
2.95.2 для ultrasparc с опциями
-mcpu=v8 -Wa,-xarch=v8plusa
дает еще 4% эффективности.
--log-bin
сделает MySQL
примерно на 1% медленнее.
-fomit-frame-pointer
или -fomit-frame-pointer
-ffixed-ebp
делает mysqld
на 1-4% быстрее.Дистрибутив MySQL-Linux, собранный в MySQL AB, использовал
pgcc
, но из-за ошибки при работе на процессорах AMD (причина в
компиляторе, а не в процессорах, они-то как раз отменные!) теперь снова
применяется обычный gcc, и так будет до тех пор, пока та ошибка не будет
решена авторами транслятора. Тем временем, если Вы имеете не-AMD машину, Вы
можете попробовать применить pgcc
. Правда, не очень ясно, кто
победит в этом споре: то ли более совершенный компилятор pgcc
,
то ли процессоры от AMD, которые просто по конструкции быстрее Intel...
Стандартный двоичный дистрибутив MySQL для Linux скомпонован статически,
чтобы получить большие быстродействие и переносимость.
Список ниже указывает некоторые из путей, которыми сервер
mysqld
использует память. Там, где это нужно и важно, указаны
имена соответствующих переменных сервера.
key_buffer_size
) разделен всеми
потоками. Другие буфера, используемые сервером, распределены как необходимо.
Подробности в разделе "5.5.2
Настройка параметров сервера".
thread_stack
),
буфер подключений (переменная net_buffer_length
) и буфер
результатов (переменная net_buffer_length
). Буфер подключений и
буфер результатов будут динамически расширены до
max_allowed_packet
, когда это будет необходимо. Когда запрос
обрабатывается, копия текущей строки запроса также распределена.
record_buffer
).
record_rnd_buffer
).
BLOB
сохранены на
диске. Одна проблема в MySQL до Version 3.23.2 состоит в том, что, если
таблица HEAP превышает размер tmp_table_size
, Вы получите ошибку
The table tbl_name is full
. В более новых версиях это обработано
автоматической заменой таблиц в памяти на дисковые по мере необходимости.
Чтобы обойти эту проблему Вы можете увеличивать временный размер таблицы,
устанавливая опцию tmp_table_size
в mysqld
или
устанавливая в программе пользователя SQL-опцию SQL_BIG_TABLES
.
Подробности в разделе "5.5.6 Синтаксис
SET
". В MySQL Version 3.20 максимальный размер временной
таблицы был record_buffer*16
так, что, если Вы используете эту
версию, Вы должны увеличить значение record_buffer
. Вы можете
также запустить mysqld
с опцией --big-tables
,
чтобы всегда сохранять временные таблицы на диске. Однако, это будет плохо
воздействовать на быстродействие очень многих сложных запросов.
malloc()
и free()
).
3*n
(где n
максимальная длина строки, не
считая столбцы типа BLOB
). BLOB
использует от 5 до
8 байт плюс длина данных BLOB
. Драйвер таблиц
ISAM
/MyISAM
распределяет один буфер строк
дополнительно для внутреннего использования.
BLOB
, буфер будет
расширен динамически, чтобы читать большие значения BLOB
.
Если Вы просматриваете таблицу, распределяется буфер такого размера, как
самое большое значение BLOB
.
mysqladmin flush-tables
закрывает все таблицы,
которые не находятся в использовании, и отмечает все таблицы, находящиеся в
использовании, чтобы они были закрыты, когда работающий в настоящее время
поток завершится. Это действительно освободит много памяти.ps
и другие программы состояния системы может сообщать, что
mysqld
использует много памяти. Это может быть вызвано стеками
потоков на различных адресах памяти. Например, Solaris-версия ps
считает неиспользуемую память между стеками как используемую память! Вы
можете выяснить это, проверяя доступный своп командой swap -s
.
Сервер mysqld
проверен с коммерческими детекторами утечки
памяти, так что в нем не должно иметься никаких утечек памяти.
Когда новый процесс соединяется с mysqld
, он запустит новый
поток, чтобы обработать запрос. Этот поток сначала проверит, находится ли
hostname в кэше hostname. Если нет, поток вызовет
gethostbyaddr_r()
и gethostbyname_r()
, чтобы
получить адрес машины.
Если операционная система не поддерживает вышеупомянутые
поточно-безопасные обращения, поток блокирует mutex и вызывает
gethostbyaddr()
и gethostbyname()
. Обратите
внимание, что в этом случае никакой другой поток не может обработать другое
имя до завершения первого потока.
Вы можете отключить поддержку DNS запуском mysqld
с опцией
--skip-name-resolve
. В этом случае Вы можете использовать только
IP-адреса в таблицах привилегий MySQL.
Если Вы имеете очень медленный DNS и много компьютеров, Вы можете
получать большую эффективность отключая DNS опцией
--skip-name-resolve
или увеличивая определение
HOST_CACHE_SIZE
(значение по умолчанию: 128) с последующей
перекомпиляцией сервера mysqld
.
Вы можете отключать кэш hostname с помощью опции
--skip-host-cache
. Вы можете очищать кэш hostname с помощью
команд FLUSH HOSTS
или mysqladmin flush-hosts
.
Если Вы не хотите позволять подключения по TCP/IP
, Вы можете
сделать это, запуская mysqld
с опцией
--skip-networking
.
SET
SET [OPTION] SQL_VALUE_OPTION=value, ...
SET OPTION
устанавливает различные параметры, которые
воздействуют на работу клиента или сервера. Любая опция, которую Вы
устанавливаете, остается в силе до завершения текущего сеанса, или пока Вы не
установите ее в другое значение.
CHARACTER SET character_set_name|DEFAULT
character_set_name
является cp1251_koi8
, но Вы можете легко добавлять новые
отображения, редактируя файл sql/convert.cc в дистрибутиве исходных
текстов MySQL. Отображение значения по умолчанию может быть восстановлено,
используя значение DEFAULT
для переменной
character_set_name
. Обратите внимание, что синтаксис для
установки опции CHARACTER SET
отличается от синтаксиса для
установки других параметров.
PASSWORD=PASSWORD('some password')
PASSWORD FOR user=PASSWORD('some password')
mysql
может делать это. Пользователь должен быть указан в формате
user@hostname
, где user
и hostname
указаны точно так, как они перечислены в столбцах User
и
Host
записи в таблице mysql.user
. Например, если Вы
имели запись с полями User
и Host
равными
bob
и %.loc.gov
, Вы будете писать:
mysql> SET PASSWORD FOR bob@"%.loc.gov"=PASSWORD("newpass"); или mysql> UPDATE mysql.user SET password=PASSWORD("newpass") where user="bob' and host="%.loc.gov";
SQL_AUTO_IS_NULL=0|1
1
(значение по умолчанию), то можно
находить последнюю вставленную строку для таблицы с поддержкой
auto_increment применением следующей конструкции: WHERE
auto_increment_column IS NULL
. Это используется некоторыми программами
ODBC, например, Access.
AUTOCOMMIT=0|1
1
, все изменения для таблицы будут
выполнен сразу. Чтобы запустить многокомандную транзакцию, Вы должны
использовать инструкцию BEGIN
. Если установлено в 0
,
Вы должны использовать COMMIT
/ROLLBACK
, чтобы
принять или отменить эту транзакцию. Обратите внимание, что, когда Вы
изменяете режим с не-AUTOCOMMIT
на AUTOCOMMIT
,
MySQL автоматически будет делать COMMIT
на открытых транзакциях.
SQL_BIG_TABLES=0|1
1
, все временные
таблицы сохранены на диске, а не в памяти. Это будет немного медленнее, но Вы
не будете получать ошибку The table tbl_name is full
для больших
операций SELECT
, которые требуют большой временной таблицы.
Значение по умолчанию для нового подключения 0
(то есть
использовать временные таблицы в памяти).
SQL_BIG_SELECTS=0|1
0
, MySQL прервется, если
SELECT
, вероятно, будет брать очень длительное время. Это
полезно, когда была выдана нецелесообразная инструкция WHERE
.
Большой запрос определен как SELECT
, которому, вероятно,
придется исследовать больше, чем max_join_size
строк. Значение
по умолчанию для нового подключения: 1
(это позволяет выполнять
все инструкции SELECT
).
SQL_BUFFER_RESULT=0|1
SQL_BUFFER_RESULT
вынудит результат SELECT
попасть во временную таблицу. Это поможет MySQL освободить блокировку таблицы
пораньше и поможет в случаях, где требуется длительное время, чтобы послать
набор результатов пользователю.
SQL_LOW_PRIORITY_UPDATES=0|1
1
, все инструкции INSERT
,
UPDATE
, DELETE
и LOCK TABLE WRITE
ждут до тех пор, пока не останется ни одного ждущего обработки запроса
SELECT
или LOCK TABLE READ
на данной таблице.
SQL_MAX_JOIN_SIZE=value|DEFAULT
SELECT
, которые, вероятно, будут должны
исследовать больше, чем value
комбинаций строк. Устанавливая это
значение, Вы можете захватывать SELECT
, где ключи не
используются правильно. Установка этого к иному значению, чем
DEFAULT
сбросит флажок SQL_BIG_SELECTS
. Если Вы
снова устанавливаете флажок SQL_BIG_SELECTS
, переменная
SQL_MAX_JOIN_SIZE
будет игнорироваться. Вы можете устанавливать
значение по умолчанию для этой переменной, запуская mysqld
с
опцией -O max_join_size=#
.
SQL_SAFE_UPDATES=0|1
1
, MySQL прервется, если
UPDATE
или DELETE
не использует ключ или
LIMIT
в предложении WHERE
. Это делает возможным
захватить неправильные модификации при создании SQL-команды вручную.
SQL_SELECT_LIMIT=value|DEFAULT
SELECT
. Если SELECT
имеет предложение
LIMIT
, то LIMIT
имеет приоритет над значением в
SQL_SELECT_LIMIT
. Значение по умолчанию для нового подключения:
``unlimited''. Если Вы изменили ограничение, значение по умолчанию может быть
восстановлено, используя значение DEFAULT
.
SQL_LOG_OFF=0|1
1
, никакая регистрация не будет выполнена
в стандартный файл регистрации для этого пользователя, если пользователь
имеет привилегию process. Это не воздействует на
файл регистрации модификаций!
SQL_LOG_UPDATE=0|1
0
, никакая регистрация не будет выполнена
в файл регистрации модификаций для этого пользователя, если пользователь
имеет привилегию process. Это не воздействует на
стандартный файл регистрации!
SQL_QUOTE_SHOW_CREATE=0|1
1
, SHOW CREATE TABLE
цитирует имена столбцов и таблиц. Это включено по умолчанию
для репликации таблиц с нестандартными именами столбцов. Подробности в
разделе "4.5.5.8
SHOW CREATE TABLE
".
TIMESTAMP=timestamp_value|DEFAULT
timestamp_value
должен быть в формате UNIX
Epoch timestamp, а не MySQL timestamp.
LAST_INSERT_ID=#
LAST_INSERT_ID()
. Это будет сохранено в файле регистрации
модификаций, когда Вы используете LAST_INSERT_ID()
в команде,
которая модифицирует таблицу.
INSERT_ID=#
INSERT
или ALTER TABLE
при вставке значения
AUTO_INCREMENT
. Это главным образом используется вместе с файлом
для регистрации модификаций.hdparm -m 16 -d 1Обратите внимание, что эффективность и надежность при использовании вышеупомянутого зависят от Ваших аппаратных средств, так что я настоятельно советую, чтобы Вы проверили Вашу систему полностью после использования
hdparm
. Пожалуйста, проконсультируйтесь с man-страницей на
hdparm
для получения большего количества информации. Если
hdparm
не используется грамотно, можно прихлопнуть все данные на
диске. Резервируйте все перед экспериментированием.
Вы можете перемещать таблицы и базы данных из каталога баз данных куда хотите и заменять их на символические связи с новыми расположениями. Вы могли бы сделать это для решения проблем с диском, например, переместить базу данных на файловую систему с большим количеством свободного пространства или увеличить быстродействие Вашей системы, распространяя Ваши таблицы на различные диски.
Надо сначала создать каталог на некотором диске, где Вы имеете свободное пространство, и затем создать ссылку туда из каталога баз данных MySQL:
shell> mkdir /dr1/databases/test shell> ln -s /dr1/databases/test mysqld-datadir
MySQL не поддерживает привязку одного каталога к нескольким базам данных.
Замена каталога баз данных символической связью будет работать прекрасной,
пока Вы не сделаете символическую связь между базами данных. Предположим, что
Вы имеете базу данных db1
в каталоге данных MySQL, а затем
делаете ссылку db2
, которая указывает на db1
:
shell> cd /path/to/datadir shell> ln -s db1 db2
Теперь для любой таблицы tbl_a
в db1
также
имеется таблица tbl_a
в db2
. Если один поток
модифицирует db1.tbl_a
, а другой в то же время правит
db2.tbl_a
, они точно передерутся.
Если Вы хотите разрешить такие обращения, Вы должны изменить следующий код в файле исходного текста mysys/mf_format.c:
if (flag & 32 || (!lstat(to,&stat_buff) && S_ISLNK(stat_buff.st_mode)))
на
if (1)
В Windows Вы можете использовать внутренние символические связи с
каталогами, компилируя MySQL с опцией -DUSE_SYMDIR
. Это
позволяет Вам размещать различные базы данных на разных дисках. Подробности в
разделе "2.6.2.5 Размещение
данных на разных дисках в Windows".
До MySQL 4.0 не стоило пользоваться ссылками без их тщательнейшего
контроля. Проблема состоит в том, что, если Вы выполняете ALTER
TABLE
, REPAIR TABLE
или OPTIMIZE TABLE
на
таблице со связью, ссылка будет удалена и заменена первоначальными файлами.
Это случается потому, что вышеупомянутая команда работает, создавая временный
файл в каталоге баз данных, а когда команда завершится, первоначальный файл
она заменит на временный файл.
Вы не должны связывать таблицы на системе, которая не имеет полностью
рабочее обращение realpath()
. По крайней мере Linux и Solaris
точно поддерживают realpath()
.
В MySQL 4.0 ссылки полностью поддержаны только для таблиц
MyISAM
. Для других типов таблиц Вы, вероятно, получите странные
проблемы при выполнении любой из вышеупомянутых команд.
Обработка символических связей в MySQL 4.0 работает следующим образом:
mysqld
не запущен) или с помощью команды INDEX/DATA
DIRECTORY="path-to-dir"
в CREATE TABLE
.
myisamchk
теперь уже не будет заменять ссылки на реальные
файлы, а работает непосредственно на нужных файлах. Любые временные файлы
будут созданы в том же самом каталоге, где лежит файл данных или индекса.
mysqld
как root, и не позволять кому попало иметь доступ для
записи к каталогам баз данных MySQL.
ALTER TABLE RENAME
и
не измените базу данных, ссылка в каталоге базы данных будет переименована,
как и файл данных/индекса.
ALTER TABLE RENAME
, чтобы переместить
таблицу в другую базу данных, то таблица будет перемещаться в другой каталог
баз данных, а старая ссылка и файл, на который она указывала, удалятся.
--skip-symlink
при запуске mysqld
, чтобы
гарантировать, что никто не может удалять или переименовывать файл вне
каталога данных MySQL.Свойства, которые еще не поддержаны:
ALTER TABLE
игнорирует все опции
INDEX/DATA DIRECTORY="path"
.
CREATE TABLE
не сообщает, имеет ли таблица ссылки.
mysqldump
не включает информацию ссылок в вывод.
BACKUP TABLE
и RESTORE TABLE
не
обрабатывают ссылки вообще.