Удалить предложение DEFINER из дампов MySQL
У меня есть дамп MySQL одной из моих баз. В нем есть предложения DEFINER, которые выглядят так:
"DEFINER=`root`@`localhost`"
а именно, эти предложения DEFINER находятся в моем представлении CREATE и инструкции CREATE PROCEDURE. Есть ли способ удалить эти предложения DEFINER из моего файла дампа?
21 ответов:
Я не думаю, что есть способ, чтобы игнорировать добавлять
DEFINERs на свалку. Но есть способы удалить их после создания файла дампа.
откройте файл дампа в текстовом редакторе и замените все вхождения
DEFINER=root@localhostС пустой строкой ""редактировать дамп (или трубу вывода) с помощью
perl:perl -p -i.bak -e "s/DEFINER=\`\w.*\`@\`\d[0-3].*[0-3]\`//g" mydatabase.sqlmysqldump ... | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' > triggers_backup.sql
вы можете удалить с помощью SED
sed -i 's/DEFINER=[^*]*\*/\*/g' mydump.sqlВ MacOS:
sed -i '' 's/DEFINER=[^*]*\*/\*/g' mydump.sql
начиная с версии mysql 5.7.8 вы можете использовать
--skip-definerопция с mysqlpump, например:mysqlpump --skip-definer -h localhost -u user -p yourdatabaseсм. обновленное руководство mysql по адресу http://dev.mysql.com/doc/refman/5.7/en/mysqlpump.html#option_mysqlpump_skip-definer
в соответствии с рекомендациями другого, вот пример того, как удалить определитель из дампа, после завершения дампа:
mysqldump -u user --password='password' -h localhost database | grep -v "50013 DEFINER" > dump.sql
я использовал эти идеи, чтобы удалить предложение DEFINER из моего собственного вывода mysqldump, но я взял более простой подход:
просто удалить
!перед кодом и определителем, а остальная часть комментария становится обычным комментарием.пример:
/*!50017 DEFINER=`user`@`111.22.33.44`*/оказывается беспомощным, как это делать ..
/* 50017 DEFINER=`user`@`111.22.33.44`*/самое простое регулярное выражение, хотя, чтобы удалить ! а цифры
mysqldump | /usr/bin/perl -pe 's/\!\d+ DEFINER/DEFINER/' > dumpfile.sqlчто удаляет
!#### DEFINERи заменяет с определителем ... вы могли бы удалить DEFINER тоже, это не имеет значения-один раз "!"ушел
Как уже упоминалось, удаление определителя с любым регулярным выражением не слишком сложно. Но другие примеры лишили определения представления для меня.
это регулярное выражение, которое работает для меня:
sed -e 's/DEFINER=[^ ]* / /'
для автоматического решения, вы можете посмотреть на
mysqlmigrate. Это обертка Bash вокругmysqldumpчто позволяет переносить базы данных и игнорировать операторы DEFINER. Пример:$ mysqlmigrate -u root -p pass --ignore-definer from_db to_dbhttp://thesimplesynthesis.com/post/mysqlmigrate (или GitHub)
в противном случае, да, команда, как указывает Абхай, необходима:
$ mysqldump -u root -ppass the_db | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' > the_db.sql
Не уверен, что это помогает, Но я использую Sqlyog Community Edition, доступный по адресу: -
https://code.google.com/p/sqlyog/wiki/Downloads
при сбросе sql или копировании в другую базу данных он позволяет вам "игнорировать определитель"
Это бесплатно и обеспечивает основную функциональность, что многие люди требуют
существует также платная версия доступна с: -
https://www.webyog.com/product/sqlyog
Ура
вот полное рабочее решение для удаления информации определителя для
MySQL 5.6.xи Linux.(Проверено наCentOS 6.5).обычно мы должны заменить следующие записи из дампа Mysql (если они взяты вместе с данными и триггерами/подпрограммами/функциями).
/*!50013 DEFINER=`MYSQLUSER`@`localhost` SQL SECURITY DEFINER */ /*!50013 DEFINER=`MYSQLUSER`@`%` SQL SECURITY DEFINER */ CREATE DEFINER=`MYSQLUSER`@`%` PROCEDURE `PROCEDURENAME`( CREATE DEFINER=`MYSQLUSER`@`localhost` PROCEDURE `PROCEDURENAME`( CREATE DEFINER=`MYSQLUSER`@`%` FUNCTION `FUNCTIONNAME`( CREATE DEFINER=`MYSQLUSER`@`localhost` FUNCTION `FUNCTIONNAME`( /*!50003 CREATE*/ /*!50017 DEFINER=`MYSQLUSER`@`%`*/ /*!50003 TRIGGER `TRIGGERNAME` /*!50003 CREATE*/ /*!50017 DEFINER=`MYSQLUSER`@`localhost`*/ /*!50003 TRIGGER `TRIGGERNAME`дамп был взят с помощью команды ниже mysqldump.
mysqldump -uMYSQLUSER -pPASSWORD DATABASENAME -R > dbdump.sqlнеобходимый файл дампа без информации определителя может быть получен с помощью следующих трех команд.
Command-1 sed -i 's|DEFINER=[^*]*\*|\*|g' [PATH/]dbdump.sql Command-2 find -name [PATH/]dbdump.sql | xargs perl -pi -e "s/ DEFINER=\`MYSQLUSER\`@\`localhost\`//" Command-3 find -name [PATH/]dbdump.sql | xargs perl -pi -e "s/ DEFINER=\`MYSQLUSER\`@\`%\`//"если дамп файл находится в вашей текущей папке, а затем игнорировать [путь/].
если данные в таблицах очень велики, то возьмите дамп в двух файлах, в одном файле дампа возьмите дамп с данными, а в другом файле дампа возьмите дамп только скриптов (триггеры/функции/процедуры.) и выполните вышеуказанные три команды на 2-м файле дампа (скриптов).
быстрый способ сделать это-передать вывод mysqldump через sed удалить
DEFINERоператоры, завернутые в условные комментарии. Я использую это, чтобы удалитьDEFINERСCREATE TRIGGERзаявления, но вы можете настроить номер версии комментария условия в регулярном выражении в соответствии с вашими целями.mysqldump -u user --password='password' -h localhost database | \ sed 's/\/\*!50017 DEFINER=`.*`@`.*`\*\///'
вы должны посмотреть ответ здесь: https://dba.stackexchange.com/questions/9249/how-do-i-change-the-definer-of-a-view-in-mysql/29079#29079
лучший способ, на мой взгляд, решить эту проблему, не добавляет дополнительный разбор строки с sed или grep или любой другой, вместо этого mysqldump способен генерировать хороший дамп, добавив --single-transaction
для меня это работает:
perl -p -i.bak -e "s/DEFINER=[^ |\s]*//g" yourdump.dmp. Это удалило DEFINER=root@localhost из моего дампа, на каждом создании процедуры statment
еще один вариант на OSX, чтобы удалить определители в файле:
sed -i '' 's/DEFINER=`[^`][^`]*`@`[^`][^`]*`//g' file.sql
замените всех пользователей определителя на CURRENT_USER. В моем скрипте gradle, который создает резервную копию, мой сценарий замены выглядит так:
ant.replaceregexp(file: "$buildDir/sql/setupDB.sql", match: "`${project.ext.prod_db_username}`@`%`", replace: "CURRENT_USER", byline: true);который на самом деле просто вызывает ANT. Тогда вам не придется беспокоиться об этом.
на машинах Linux вы можете использовать этот однострочный:
mysql -uuser -ppwd -A --skip-column-names -e"SELECT CONCAT('SHOW CREATE VIEW ',table_schema,'.',table_name,';') FROM information_schema.tables WHERE engine IS NULL and table_schema like 'mydb%'" | mysql -uuser -ppwd -A --skip-column-names | sed -rn 's/.*?VIEW ([^\s]+?) (AS .*?)\s([^\s]+?)\s([^\s]+?)/DROP VIEW ;\nCREATE VIEW ;/p' | mysql -uuser -ppwd -A --skip-column-namesвам нужно только заменить строки полужирным шрифтом с вашими учетными данными пользователя БД и именем базы данных / подобным шаблоном.
подробнее здесь: http://blog.novoj.net/2014/05/16/recreate-mysql-views-without-definer-one-liner-solution-linux/
единственный способ заставить его работать под Windows:
установить http://gnuwin32.sourceforge.net/ иметь sed в командной строке и добавить его в Windows путь: D:\programs\GetGnuWin32\bin;
sed -i "s|DEFINER=`mydbuser`@`%%` SQL SECURITY DEFINER||g" "D:/prod_structure.sql" sed -i "s|DEFINER=`mydbuser`@`%%`||g" "D:/prod_structure.sql" mysqldump -P{port} -h{host} -u{user} -p{password} --routines --no-data --lock-tables=false database_prod > D:\prod_structure.sql
спасибо всем за подсказки. Будучи ленивым, я написал сценарий с именем: "MYsqldump":
DB= HOST= USER= MYSQLDUMP='/usr/bin/mysqldump' PARAMS="--complete-insert --disable-keys=0 --extended-insert=0 --routines=0 --skip-comments" DAY=`date +%d` MONTH=`date +%m` YEAR=`date +%Y` FILE=$DB.$DAY-$MONTH-$YEAR.sql if (( $# < 3 )) ; then echo "" echo "usage: MYsqldump <db> <host> <user>" echo "" exit 1 fi $MYSQLDUMP -h $HOST -u $USER -p $PARAMS $DB | grep -v '/*!50013 DEFINER' > $FILE
, например:
DELIMITER ;; CREATE DEFINER=`mydb`@`localhost` FUNCTION `myfunction`() RETURNS int(11) begin (...) end ;;попробуйте это:
mysqldump --force --routines --opt --user=myuser --databases mydb | sed -e 's/DEFINER=`.*`@`.*`\ //g'
самое простое регулярное выражение, которое работает для меня со всеми объектами-это:
sed 's/DEFINER=[^ ]*`//' ...отметим, что
quote-namesдолжен бытьTRUE(по умолчанию).надеюсь, что в новых версиях переключатель
--skip-definerвведенный в mysqlpump в версии 5.7 приходит к mysqldump, тоже.
я использовал скрипт PowerShell для удаления всех строк с помощью
DEFINER:get-content $file_in_full_path / select-string-pattern $line_string_delete-notmatch | Out-File-width 1000000000-кодировка по умолчанию $file_out_full_path
откройте свою базу данных с помощью любого редактора, который я использовал с notepad++,
найти все испытание, что
DEFINER=root@localhostи заменить его ничем(""), т. е.. удалить его.затем вы можете импортировать его на любой хост, который вы хотите.
Comments