MySQL 덤프에서 DEFINER 절 제거


114

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

"DEFINER=`root`@`localhost`" 

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


몇 년 전에 버그가보고되었지만 버려진 것처럼 보입니다 : bugs.mysql.com/bug.php?id=24680
1234ru

답변:


109

나는 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

1
@FastTrack, 전체 문자열을 제거하십시오.
Abhay 2012

3
DEFINER를 제거하는 대신 다음과 같이 CURRENT_USER로 설정할 수 있음을 언급하는 것이 좋습니다. sed -E 's/DEFINER=[^ ]+@ [^] + /DEFINER=CURRENT_USER/g' dump.sql > new_dump.sql제한 / 액세스 제어를 유지하는 이점이 있습니다.
4thfloorstudios

27
sed명령은 프로 시저 및 함수에서 DEFINER 절을 제거하지 않습니다. 여기 향상된 버전은 그 손잡이 뷰, 트리거, 절차, 함수 : sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | sed -e 's/DEFINER[ ]*=[ ]*[^*]*PROCEDURE/PROCEDURE/' | sed -e 's/DEFINER[ ]*=[ ]*[^*]*FUNCTION/FUNCTION/'
블라디미르 Strugatsky

4
참고로 ---이 답변 당시에는 그렇지 않았지만 MySQL> 5.6은 이제 "--skip-definer"를 옵션으로 지원하는 mysqldump (1)와 함께 제공됩니다. dev.mysql.com/doc/refman /5.7/ko/…
Kevin_Kinsey

4
아니요, mysqldump가 아니라 --skip-definer가있는 mysql p ump입니다.
Xdg

70

SED를 사용하여 제거 할 수 있습니다.

sed -i 's/DEFINER=[^*]*\*/\*/g' mydump.sql

MacOS에서 :

sed -i '' 's/DEFINER=[^*]*\*/\*/g' mydump.sql

MacOS에서 다른 점은 무엇입니까?
Alex

1
Mac의 sed에 대한 맨 페이지는 다음과 같습니다. -i extension"파일 내부 편집, 지정된 확장자로 백업 저장. 길이가 0 인 확장자를 지정하면 백업이 저장되지 않습니다. 다음과 같은 경우 0 길이 확장자를 지정하지 않는 것이 좋습니다. 내부 편집 파일, 디스크 공간이 부족한 상황에서 손상되거나 일부 콘텐츠가 발생할 위험이 있습니다. "
Chad

알아서 반갑습니다, @Chad. 저는 지금 5 년 이상 Mac에서 sed를 사용하고 있습니다. 나는 공간이나 손상된 파일에 문제가 없었습니다. 그러나 물론 고려해야 할 사항입니다. 명확히 해주셔서 감사합니다.
Ricardo Martins

Mac에서도 이러한 문제를 겪은 적이 없습니다. @Alex가 물었 기 때문에 명확히 할 것이라고 생각했습니다. :)
Chad

57

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 설명서를 참조하십시오.


8
차이 무엇을 궁금해 누구든지 mysqldumpmysqlpump- 여기에 관련 질문은 dba.stackexchange.com/questions/118846/mysqldump-vs-mysqlpump
Scadge

phpMyAdmin 및 MySQL Workbench가 설치되어 있습니다. Windows에서이 명령을 어떻게 실행합니까?
posfan12

(몇 가지 테스트 후 : -1)이 사용 information_schema.user하고, 이것은 항상 모든 사용자가 읽을 수 없습니다
bato3

17

이 아이디어를 사용하여 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도 제거 할 수 있습니다. "!" 사라


16

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

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

4
트리거의 경우 행은 다음과 같습니다. / *! 50003 CREATE * / / *! 50017 DEFINER = user@ localhost* / / *! 50003 trigger my_triggername BEFORE INSERT ON my_table FOR EACH ROW .... * / ;; 그리고 grep -v완전히 그 라인을 삭제합니다. (하지만 50017! = 50013)
Kenney

13

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

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

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

그리고 빠른 ^^ 감사합니다
케빈 Labécot

1
트리거와 함께 작동하지 않음- */. MySQL 5.6.31.
Franc Drobnič 2016 년

10

자동화 된 솔루션의 경우 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

6

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

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

5

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

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


왜 반대 투표를 했나요? 이 답변이 유용하지 않은 이유는 무엇입니까?
Jose Nobile

1
귀하의 응답은 가치있는 위치를 얻기 위해 여전히 약 90 개의 업 보트가 필요합니다. 당신은 :) 광산을 가지고
패트릭 반 베르겐에게

4

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

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

1
약간 더 읽기 쉬운 sed 문 : sed "s / DEFINER (. *?) FUNCTION / FUNCTION /"
reustmd

4

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

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

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

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

유료 버전도 있습니다 :-

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

건배


'유용하지 않음'으로 표시하는 것보다 유용하지 않다고 생각하는 이유를 답장하면 더 유용 할 것입니다.
itfidds

3

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


2

다음은 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 /]를 무시하십시오.

테이블의 데이터가 매우 큰 경우 두 파일에서 덤프를 가져오고, 하나의 덤프 파일에서 데이터와 함께 덤프를 가져오고 다른 덤프 파일에서 스크립트 만 덤프 (Triggers / Functions / Procedures.)하고 위의 세 가지를 실행합니다. 두 번째 덤프 (스크립트) 파일에 대한 명령.


1

모든 정의 자 사용자를 CURRENT_USER로 바꿉니다. 백업을 생성하는 내 gradle 스크립트에서 교체 스크립트는 다음과 같습니다.

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

정말로 ANT라고 부르는 것입니다. 그러면 그것에 대해 걱정할 필요가 없습니다.


1

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

굵게 표시된 문자열은 DB 사용자 자격 증명 및 데이터베이스 이름 / 유사 패턴으로 만 바꾸면됩니다.

자세한 정보 : http://blog.novoj.net/2014/05/16/recreate-mysql-views-without-definer-one-liner-solution-linux/


1

Windows에서 작동하도록 할 수있는 유일한 방법 :

http://gnuwin32.sourceforge.net/ 을 설치 하여 명령 줄에서 sed 하고 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

1

힌트를 주셔서 감사합니다. 게으 르기 때문에 "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

1

다음과 같은 경우 :

DELIMITER ;;
CREATE DEFINER =`mydb` @`localhost` 함수`myfunction` () 반환 int (11)
시작하다
(...)
끝 ;;

이 시도:

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

1
  1. 메모장에서 사용한 편집기로 데이터베이스를 엽니 다. ++,

  2. 모든 테스트를 찾아 DEFINER=root@localhost nothing ( "") IE로 대체하십시오 . 그것을 삭제하십시오.

그런 다음 원하는 호스트로 가져올 수 있습니다.


0

모든 객체에서 나를 위해 작동하는 가장 간단한 정규식은 다음과 같습니다.

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

참고 quote-names되어야한다 TRUE(기본값이다).

최신 버전에서는 --skip-definer버전 5.7의 mysqlpump에 도입 된 스위치 가 mysqldump에도 적용되기를 바랍니다.


0

PowerShell 스크립트를 사용하여 DEFINER다음 과 같은 모든 줄을 제거했습니다 .

get-content $ file_in_full_path | select-string -pattern $ line_string_delete -notmatch | Out-File -width 1000000000-인코딩 기본값 $ file_out_full_path


0

나를 위해 아무것도 작동하지 않았으므로 내 자신의 정규식을 작성해야했습니다.

  1. 데이터베이스를 파일, cat전체 파일 및 grep정의 자 문 으로 덤프하여 확인하십시오.

    고양이 file.sql | grep -o -E '. {, 60} DEFINER. {, 60}'

  2. 정규식 작성

  3. 이 정규식을 사용하여 덤프를 sed로 파이프하십시오. 예를 들어 내 진술은 다음과 같습니다.

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

  4. 이익!


0

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.