code

MySQL 덤프에서 DEFINER 절 제거

codestyles 2020. 8. 21. 07:46
반응형

MySQL 덤프에서 DEFINER 절 제거


내 데이터베이스 중 하나의 MySQL 덤프가 있습니다. 여기에는 다음과 같은 DEFINER 절이 있습니다.

"DEFINER=`root`@`localhost`" 

즉, 이러한 DEFINER 절은 내 CREATE VIEW 및 CREATE PROCEDURE 문에 있습니다. 내 덤프 파일에서 이러한 DEFINER 절을 제거하는 방법이 있습니까?


나는 DEFINER덤프에 s를 추가하는 것을 무시하는 방법이 없다고 생각 합니다. 그러나 덤프 파일이 생성 된 후 제거하는 방법이 있습니다.

  1. 텍스트 편집기에서 덤프 파일을 열고의 모든 항목을 DEFINER=root@localhost빈 문자열 ""로 바꿉니다.

  2. 다음을 사용하여 덤프 (또는 출력 파이프)를 편집합니다 perl.

    perl -p -i.bak -e "s/DEFINER=\`\w.*\`@\`\d[0-3].*[0-3]\`//g" mydatabase.sql
    
  3. 다음을 통해 출력을 파이프합니다 sed.

    mysqldump ... | 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-definermysqlpump와 함께 옵션을 사용할 수 있습니다. 예 :

mysqlpump --skip-definer -h localhost -u user -p yourdatabase

http://dev.mysql.com/doc/refman/5.7/en/mysqlpump.html#option_mysqlpump_skip-definer 에서 업데이트 된 mysql 설명서를 참조하십시오.


다른 사람의 권장 사항에 따라 다음은 덤프가 완료된 후 덤프에서 DEFINER를 제거하는 방법의 예입니다.

mysqldump -u user --password='password' -h localhost database | grep -v "50013 DEFINER" > dump.sql

이 아이디어를 사용하여 mysqldump 출력에서 ​​DEFINER 절을 제거했지만 더 간단한 방법을 사용했습니다.

!코드와 DEFINER 앞의를 제거하면 나머지 주석이 일반 주석이됩니다.

예:

/*!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

그러면 !#### DEFINERDEFINER가 제거 되고 대체됩니다. DEFINER도 제거 할 수 있습니다. "!" 사라


다른 사람들이 언급했듯이 모든 종류의 정규 표현식으로 정의자를 제거하는 것은 너무 복잡하지 않습니다. 그러나 다른 예제는 나를 위해 뷰 정의를 제거했습니다.

이것은 나를 위해 일한 정규식입니다.

sed -e 's/DEFINER=[^ ]* / /'

자동화 된 솔루션의 경우 mysqlmigrate. mysqldump데이터베이스를 마이그레이션하고 DEFINER 문을 무시할 수 있는 Bash 래퍼 입니다. 예:

$ mysqlmigrate -u root -p pass --ignore-definer from_db to_db

http://thesimplesynthesis.com/post/mysqlmigrate (또는 GitHub )

그렇지 않으면 예, Abhay가 지적한 것과 같은 명령이 필요합니다.

$ mysqldump -u root -ppass the_db | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' > the_db.sql

여기에서 답을 찾아야합니다 : https://dba.stackexchange.com/questions/9249/how-do-i-change-the-definer-of-a-view-in-mysql/29079#29079

내 생각에이 문제를 해결하는 가장 좋은 방법은 sed 또는 grep 또는 기타 문자열 구문 분석을 추가하지 않는 것입니다. 대신 mysqldump는 --single-transaction을 추가하여 좋은 덤프를 생성 할 수 있습니다.


이를 수행하는 빠른 방법은 sed통해 mysqldump 의 출력을 파이프하여 조건부 주석으로 래핑 된 명령문 을 제거하는 것입니다. 나는 제거하기 위해 이것을 사용 에서 문,하지만 당신은 당신의 목적에 맞게 정규식의 조건 코멘트 버전 번호를 조정할 수 있습니다.DEFINERDEFINERCREATE TRIGGER

mysqldump -u user --password='password' -h localhost database | \
  sed 's/\/\*!50017 DEFINER=`.*`@`.*`\*\///' 

도움이되는지 확실하지 않지만 SQLyog Community Edition을 사용합니다.

https://code.google.com/p/sqlyog/wiki/Downloads

SQL을 덤프하거나 다른 데이터베이스로 복사 할 때 '무시 DEFINER'가 가능합니다.

무료이며 많은 사람들이 필요로하는 기본 기능을 제공합니다.

유료 버전도 있습니다 :-

https://www.webyog.com/product/sqlyog

건배


파일 내에서 정의자를 제거하는 OSX의 또 다른 옵션 :

sed -i '' 's/DEFINER=`[^`][^`]*`@`[^`][^`]*`//g' file.sql

나를 위해 이것은 작동합니다 : perl -p -i.bak -e "s/DEFINER=[^ |\s]*//g" yourdump.dmp. 이것은 내 덤프에서 DEFINER = root @ localhost를 제거했습니다.


다음은 MySQL 5.6.x및 Linux에 대한 DEFINER 정보를 제거하는 완전한 작업 솔루션 입니다 (에서 테스트 됨 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

DEFINER 정보가없는 필수 덤프 파일은 아래의 세 가지 명령으로 얻을 수 있습니다.

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\`@\`%\`//"

덤프 파일이 현재 폴더에 있으면 [PATH /]를 무시하십시오.

If data in tables is very huge then take the dump in two files, in one dump file take the dump with data and in other dump file on take the dump of the scripts only (Triggers/Functions/Procedures.) and run the above three commands on 2nd dump(scripts) file.


Replace all of your definer users with CURRENT_USER. In my gradle script that creates the backup, my replace script looks like:

ant.replaceregexp(file: "$buildDir/sql/setupDB.sql", match: "`${project.ext.prod_db_username}`@`%`", replace: "CURRENT_USER", byline: true);

which really is just calling ANT. Then you won't have to worry about it.


On Linux machines you can use this one-liner:

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 \1;\nCREATE VIEW \1 \2;/p' | mysql -uuser -ppwd -A --skip-column-names

You have only to replace strings in bold with your DB user credentials and database name / like pattern.

More info here: http://blog.novoj.net/2014/05/16/recreate-mysql-views-without-definer-one-liner-solution-linux/


The only way I could get it working under Windows:

Install http://gnuwin32.sourceforge.net/ to have sed in the command line and add it to the Windows PATH: 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

Thank you all for the hints. Being lazy, I wrote a script named: "MYsqldump" :

DB=$1
HOST=$2
USER=$3
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

For something like:

DELIMITER ;;
CREATE DEFINER=`mydb`@`localhost` FUNCTION `myfunction`() RETURNS int(11)
begin
(...)
end ;;

Try this:

mysqldump --force --routines --opt --user=myuser --databases mydb | sed -e 's/DEFINER=`.*`@`.*`\ //g'

  1. open your database with any editor, I used with notepad++,

  2. find all test that DEFINER=root@localhost and replace it with nothing("") IE. delete it.

Then you can import it to the any host that you want.


The simplest regex that works for me with all objects is:

sed 's/DEFINER=[^ ]*`//' ...

Note that quote-names has to be TRUE (which is by default).

Hope that in newer versions the switch --skip-definer introduced in mysqlpump in version 5.7 comes to mysqldump, too.


I have used PowerShell script to remove all the lines with DEFINER:

get-content $file_in_full_path | select-string -pattern $line_string_delete -notmatch | Out-File -width 1000000000 -Encoding Default $file_out_full_path


Nothing was working for me, so I needed to write my own regex.

  1. Try to dump your database into file, cat whole file and grep only your definer statements to see them.

    cat file.sql | grep -o -E '.{,60}DEFINER.{,60}'

  2. Write your regex

  3. Pipe your dump into sed with this regex. For example mine statement is:

    mysqldump | sed -E 's//*!500[0-9][0-9] DEFINER=.+?*///' | sed -E 's/DEFINER=?[^ ]+??@?[^ ]+? ?//'

  4. Profit!


remove_definers.bat:

@echo off
(for /f "tokens=1,2*" %%a in (dumpfile.sql) do (
 if "%%b"=="" (echo %%a) else (
  echo %%b | find "DEFINER" > null && echo %%a %%c || echo %%a %%b %%c
 )
)) > dumpfile_nodefiners.sql

참고URL : https://stackoverflow.com/questions/9446783/remove-definer-clause-from-mysql-dumps

반응형