Рядки відсутні після онлайн-конвертації з MyISAM в InnoDB


16

У нас є досить невелика база даних, яку ми хотіли перетворити з MyISAM в InnoDB. Будучи нобі баз даних, ми просто перетворили (використовуючи таблицю змін), навіть не знімаючи сайт.

Тепер, коли перетворення зроблено, багато переривчастих рядків, здається, відсутні. Це можливо пов'язано з операціями під час конверсії? Або питання десь інше?


У яких таблицях відсутні рядки? Ті, які ви перетворили, чи інші таблиці?
longneck

Відповіді:


20

Виконання ALTER для зміни двигунів зберігання не призведе до зникнення рядків. Однак, дозвольте запропонувати кілька порад, оскільки ви сказали, що у вашому запитанні ви "ноби баз даних".

Коли ви змінюєте існуючу схему або робите що-небудь, що може вплинути на дані, ось кілька основних порад:

  1. Спершу зробіть резервну копію.
  2. Майте план змін.
  3. Тестуйте свій план на офлайн-хості.
  4. Скласти план тесту для порівняння даних до і після.
  5. Сплануйте та прийміть час простою.
  6. Зробіть резервну копію та знімок відразу після того, як ваш час простою вступить у дію, і ви переконаєтесь, що трафік припинився.
  7. Якщо ви працюєте з MYISAM, використовуйте "CHECK TABLE", щоб оцінити, з чим ви маєте справу перед ALTER.
  8. Скопіюйте таблицю локально на додаток до резервної копії, про всяк випадок.
  9. Дійте обережно, увімкніть "--показувати попередження" та інші результати, щоб ви мали повне зображення під час внесення змін.
  10. Якщо дані важливі для вас, найміть DBA, навіть якщо просто порадитися під час міграції, щоб у вас був досвідчений ветеран.

Можливо, я можу ввійти набагато більше, але вищесказане надасть вам варіанти, коли щось піде не так.

Що стосується ваших відсутніх даних / рядків, то для порівняння не існує способу дізнатися, чи не буде "до / після". Ви можете порівняти з останньою резервною копією, щоб принаймні перевірити це.


Я читав це. Гарний план ДР. Ваша відповідь отримує +1 за те, що я більш чутливий до питання, ніж я був на додаток до плану вперед.
RolandoMySQLDBA

1
@randy Позначив це як улюблене запитання через вашу добру відповідь
techExplorer

8

Один з найкращих способів перетворення MyISAM в InnoDB без усього простою - лише одна необхідна умова: використовувати підлеглий реплікацію.

Ось план пташиного польоту

  1. Створіть налаштування головного / підлеглого реплікації
  2. Перетворіть кожну таблицю MyISAM на підлеглому в InnoDB
  3. Наведіть свою програму на Раба

Звучить просто? За цим є багато деталей.

Створіть налаштування головного / підлеглого реплікації

Існує гладкий спосіб створити Раба без особливих порушень для Майстра. Я написав два повідомлення:

Замість того, щоб детально використовувати rsync, прочитайте ці два повідомлення.

Перетворіть кожну таблицю MyISAM на підлеглому в InnoDB

На Slave DB Ви можете виконати таку заяву SQL:

Для MySQL 5.5:

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql','performance_schema');

Версія для MySQL до MySQL 5.5

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql');

Використовуючи вихід із запиту, у вас є сценарій перетворення для підлеглого.

Ви повинні розмістити ці два рядки у верхній частині сценарію:

SET SQL_LOG_BIN = 0;
STOP SLAVE;

Сценарій спочатку відключить двійковий журнал (якщо ви налаштували підлеглий мати бінарні журнали), зупинить реплікацію та перетворить кожну таблицю MyISAM в InnoDB.

Ось як створити цей сценарій та виконати його:

SQLSTMT="SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') FROM information_schema.tables WHERE engine = 'MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema')"
INNODB_CONV_SCRIPT=MassConvertMyISAMTablesToInnoDB.sql
echo "SET SQL_LOG_BIN = 0;" > ${INNODB_CONV_SCRIPT}
echo "STOP SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Master) -u... -p... --skip-column-names -A -e"${SQL}" >> ${INNODB_CONV_SCRIPT}
echo "START SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Slave) -u... -p... --skip-column-names -A < ${INNODB_CONV_SCRIPT}

Наведіть свою програму на Раба

Виконайте SELECT запити від підлеглого. Якщо вас влаштовує вміст даних на Рабі, не соромтеся вказати свій додаток на підлеглого наступним чином:

  1. На підлеглому, запустіть SHOW SLAVE STATUS\Gі переконайтесь, що Seconds_Behind_Master дорівнює 0
  2. На підлеглому, mysqldump -h (IP Slave) -u ... -p ... --single-транзакція --програми - тригери - всі бази даних> MySQLBackup.sql (Ей, резервна копія буде добре про зараз)
  3. На Майстер запустіть service mysql stop(час початку перерви)
  4. Повторіть крок 1
  5. Наведіть свою програму на підлеглого (час закінчення часу закінчення на першому з’єднанні програми)

Якщо ви до цього моменту зробили непошкодженими, ВІТАЮТЬСЯ !!!

ДОБАВЕНИЙ БОНУС : Якщо ви встановите Master / Master Replication (він же кругова реплікація) замість Master / Slave, ви можете зробити це замість цього:

  1. На підлеглому, запустіть SHOW SLAVE STATUS\Gі переконайтесь, що Seconds_Behind_Master дорівнює 0
  2. На підлеглому, mysqldump -h (IP Slave) -u ... -p ... --single-транзакція --програми - тригери - всі бази даних> MySQLBackup.sql (Ей, резервна копія буде добре про зараз)
  3. Наведіть додаток на підлеглий (час простою починається та закінчується на першому з’єднанні програми)
  4. На новому Майстрі запустіть STOP SLAVE;
  5. На новому Майстрі запустіть CHANGE MASTER TO MASTER_HOST='';

Тепер у вас є Master / Slave заднім числом. Новий Master має дані InnoDB, а старий Master тепер є рабом з даними MyISAM. Якщо ви розділяєте читання і запис, зчитування можуть переходити з Slave (читання швидше від MyISAM, ніж InnoDB), а записи переходять до програми Master (транзакційна підтримка InnoDB). Як співає Ханна Монтана, ви отримуєте найкраще з обох світів (Так, у мене дві дочки, які люблять шоу) !!!

ДРУГИЙ ДОДАТИ БОНУС : Оскільки Майстер зараз є InnoDB, ви можете робити mysqldump від Майстра без простоїв і не втручаючись в транзакції. Єдиним недоліком є ​​збільшення процесорного і дискового вводу / виводу. Ви можете, таким чином, до mysqldump структур таблиць тільки на Master (InnoDB) і mysqldump даних тільки на підлеглому (такий дамп не матиме посилань на InnoDB або MyISAM. Це будуть просто дані) плюс mysqldump структури таблиці для підлеглого мають макет MyISAM.

Можливості можуть продовжуватися завдяки цій новій настройці ...

ОНОВЛЕННЯ 2011-08-27 19:50 EDT

Мої вибачення. Я не до кінця прочитав питання. Ви вже виконали конверсію .

Тільки якщо ви вже увімкнули двійковий журнал , і у вас є попередня резервна копія, ви могли

  • відновити / var / lib / mysql в інше місце, наприклад / var / lib / mysql2
  • бігати service mysql stop
  • бігати service mysql start --datadir=/var/lib/mysql2
  • mysqldump базу даних з цієї резервної копії в /root/olddata.sql
  • запустити mysqlbinlog проти всіх бінарних журналів в / var / lib / mysql (не / var / lib / mysql2) з моменту останньої резервної копії в /root/changes.sql
  • Завантажте change.sql в mysql (оскільки він все ще вказує на / var / lib / mysql2)

Це має зафіксувати все, що було записано, і перетворення повинно розпочатись. Знову ж таки, це все, що стосується вас, у вас уже було ввімкнено бінарний журнал до останньої резервної копії . Інакше мої співчуття.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.