Я разработчик PHP, поэтому не будь строгим. У меня большой дамп таблицы ~ 5,5 ГБ. Наш премьер-министр решил создать в нем новую колонку для выполнения новой функции. Таблица InnoDB, так что я попробовал:
Изменить таблицу на экране с помощью блокировки таблицы. Взял ~ 30 часов и ничего. Так что я просто остановил это. Сначала я ошибся, потому что не завершил все транзакции, но во 2-й раз не было мультиблока. Статус был
copy to tmp table
.Поскольку мне также необходимо применить разбиение для этой таблицы, мы решили сделать дамп, переименовать и создать таблицу с тем же именем и новой структурой. Но dump делает строгую копию (по крайней мере, я не нашел что-то еще). Поэтому я добавил, чтобы создать новый столбец
sed
и запросить его. Но начались странные ошибки. Я считаю, что это было вызвано кодировкой. Таблица в utf-8 и файл стали us-ascii послеsed
. Поэтому я получил ошибки (неизвестная команда '\' ') на 30% данных. Так что это тоже плохой путь.
Каковы другие варианты для достижения этой цели и повышения производительности (я могу сделать это с помощью PHP-скрипта, но это заняло целую вечность). Каковы будут показатели INSERT SELECT
в этом случае.
Спасибо за любое продвижение.
SET NAMES utf8
и. Но мнеCOLLATION
кажется, почему 30% данных повреждены послеsed
. Я думаю, что массовая загрузка будет самой быстрой, но, может быть, существует нечто большее, чего мне не хватает. Спасибо МаркВаша идея sed - достойный метод, но без ошибок или команды, которую вы выполнили, мы не сможем вам помочь.
Тем не менее, общеизвестным способом внесения онлайн-изменений в большие таблицы является pt-online-schema-change . Упрощенный обзор того, что делает этот инструмент, скопирован из документации:
Этот метод также может занять некоторое время, но во время процесса исходная таблица будет полностью пригодна для использования.
источник
'D\'agostini'
вызовет ошибкуunknown command '\''
. Но не всегда, как в 30% случаев. Это странно и глючит. То же самое происходит даже с дампами hex-блобов. Спасибо, Дерек.alter table add column, algorithm=inplace, lock=none
изменит таблицу MySQL 5.6 без копирования таблицы и без влияния блокировки.Только что проверил это вчера, массово вставил 70К строк в таблицу разделов 780К строк, по 10К строк в каждый раздел с 5-секундным перерывом в спящем режиме для обеспечения другой пропускной способности.
Запустил массовые вставки, затем в отдельном сеансе запустил онлайн-
alter
оператор, описанный выше, в MySQL Workbench,alter
завершил до вставок, добавил два новых столбца, и в результате изменения не появилось ни одной строки, означающей, что MySQL не скопировал ни одной строки.источник
В настоящее время лучшим вариантом для изменения огромных таблиц является, вероятно, https://github.com/github/gh-ost.
gh-ost - это решение для миграции онлайн-схем без Mygger для MySQL. Он является тестируемым и обеспечивает паузу, динамическое управление / реконфигурацию, аудит и множество преимуществ.
gh-ost создает легкую рабочую нагрузку на главном сервере во время миграции, отделенную от существующей рабочей нагрузки на перенесенной таблице.
Он был разработан на основе многолетнего опыта работы с существующими решениями и изменяет парадигму миграции таблиц.
источник
Я думаю, что Mydumper / Myloader - хороший инструмент для таких операций: становится лучше с каждым днем. Вы можете использовать свои процессоры и загружать данные параллельно: http://www.percona.com/blog/2014/03/10/new-mydumper-0-6-1-release-offers-several-performance-and- удобство-функции /
Мне удалось загрузить сотни гигабайтных таблиц MySQL за несколько часов.
Теперь, когда дело доходит до добавления нового столбца, это сложно, так как MySQL копирует всю таблицу в
TMP
область памяти с помощью.ALTER TABLE...
Хотя MySQL 5.6 говорит, что он может вносить изменения в онлайн-схемы, мне не удалось сделать их онлайн для больших таблиц без блокировки раздора пока нет.источник
у меня просто была такая же проблема. Небольшое решение:
CREATE TABLE new_table SELECT * FROM oldtable;
УДАЛИТЬ ИЗ new_table
ALTER TABLE new_table ADD COLUMN new_column int (11);
INSERT INTO new_table выберите *, 0 из old_table
удалить таблицу old_table; переименовать таблицу new_table в old_table;
источник