MySQL에서 권한을 내 보낸 다음 새 서버로 가져 오려면 어떻게해야합니까?


88

mysqldump를 사용하여 데이터베이스를 내보내거나 가져 오는 방법을 알고 있으며 새 서버에 대한 권한을 얻는 방법은 무엇입니까?

추가 포인트의 경우 이미 새로운 데이터베이스에 기존 데이터베이스가 몇 개 있습니다. 기존 데이터베이스를 두 번 사용하지 않고 이전 서버 권한을 가져 오는 방법은 무엇입니까?

기존 서버 : 5.0.67-community

새 서버 : 5.0.51a-24 + lenny1

편집 : 이전 서버에서 db 'mysql'덤프를 가져 왔으며 이제 새 서버에서 'mysql'db와 병합하는 올바른 방법을 알고 싶습니다.

phpMyAdmin을 사용하여 직선 '가져 오기'를 시도한 결과 복제본 (이미 수동으로 마이그레이션 한 것)에 관한 오류가 발생했습니다.

누구나 두 개의 'mysql'데이터베이스를 병합하는 우아한 방법을 가지고 있습니까?


1. PHPMyAdmin을 사용해야합니까? 그렇다면 PHPMyAdmin 특정 지침을 작성해 드리겠습니다. 2. "select * from mysql.user limit 1;"을 시도하면 PHPMyAdmin에서 결과 또는 오류가 발생합니까?
Bruno Bronosky

1
아래에서 언급했듯이 Richard의 mygrants script는 보조금 정보를 얻는 좋은 방법이라고 생각합니다. 그러나 덤프 파일을 편집하여 이미 존재하는 사용자의 사용자 테이블에 INSERT를 주석 처리 할 수도 있습니다. 그런 다음 이전 서버에서 복원 된 DB에 대한 권한이 복사됩니다. 새 상자에 복원 한 일부 데이터베이스에 대해 수동으로 권한을 할당 한 경우 권한 파일에서이 테이블 이름을 찾아서 주석 처리하십시오. 나중에 flush_privileges를 잊지 마십시오. grahamwideman.com/gw/tech/mysql/perms/index.htm
nedm

답변:


169

mysql DB를 망쳐 놓지 마십시오. users 테이블보다 훨씬 더 많은 일이 있습니다. 최선의 방법은 " SHOW GRANTS FOR"명령입니다. 내 .bashrc (실제로 내 .bashrc에서 제공하는 .bash_aliases)에는 많은 CLI 유지 관리 별칭과 함수가 있습니다. 이 기능 :

mygrants()
{
  mysql -B -N $@ -e "SELECT DISTINCT CONCAT(
    'SHOW GRANTS FOR \'', user, '\'@\'', host, '\';'
    ) AS query FROM mysql.user" | \
  mysql $@ | \
  sed 's/\(GRANT .*\)/\1;/;s/^\(Grants for .*\)/## \1 ##/;/##/{x;p;x;}'
}

첫 번째 mysql 명령은 SQL을 사용하여 두 번째 mysql 명령으로 파이프되는 유효한 SQL을 생성합니다. 그런 다음 출력은 sed를 통해 파이프되어 예쁜 주석을 추가합니다.

명령의 $ @를 사용하면 다음과 같이 호출 할 수 있습니다. mygrants --host = prod-db1 --user = admin --password = secret

다음과 같이 전체 유닉스 툴킷을 사용할 수 있습니다.

mygrants --host=prod-db1 --user=admin --password=secret | grep rails_admin | mysql --host=staging-db1 --user=admin --password=secret

이것이 사용자를 이동시키는 올바른 방법입니다. MySQL ACL은 순수 SQL로 수정되었습니다.


이것은 실제로 훌륭한 bash 도우미 기능입니다. 그 결과를 가져 와서 새 서버에서 실행할 수 있으며 권한이 올 바르고 정확하게 입력됩니다.
Jeremy Bouse

1
나는 당신의 기능을 좋아합니다. 오늘 많은 일을 저축했습니다. 감사합니다, 감사합니다, 감사합니다 ...
Fabio

2
이것은 훌륭하지만 하나의 큰 결함이 있습니다. 추가 "\"는 데이터베이스 이름의 밑줄에 추가되므로 예를 들어 foo_bar라는 데이터베이스에 대한 특정 권한을 가진 사용자가있는 경우 foo_bar 대신 foo \ _bar로 렌더링되므로 올바르게 가져올 수 없습니다. . 최소한 스크립트의 출력을 SQL 파일로 저장 한 다음 새 서버로 가져 오는 경우에 발생합니다. 나는 한 줄에 수출과 수입의 직접 배관을 시도하지 않았습니다.
matteo

1
이 명령에주의하십시오. 당신이있는 경우 user테이블 호스트를 가진 사용자 %만 다음에 db어디에 테이블이 항목이 host명시 적 값에서 해당 항목 db의 표는이 방법을 사용하여 검색되지 않습니다.
Mitar

1
@matteo -r함수에서 두 번째 mysql 명령에 추가 하면 이중 이스케이프는로 출력되지 않습니다 mysql. 예 :mysql -r $@
lifo

45

MySQL 인스턴스에서 SQL Grants를 추출하는 방법에는 두 가지가 있습니다

방법 # 1

Percona Toolkit에서 pt-show-grants 를 사용할 수 있습니다

MYSQL_CONN="-uroot -ppassword"
pt-show-grants ${MYSQL_CONN} > MySQLUserGrants.sql

방법 # 2

pt-show-grants다음과 같이 에뮬레이션 할 수 있습니다

MYSQL_CONN="-uroot -ppassword"
mysql ${MYSQL_CONN} --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') FROM mysql.user WHERE user<>''" | mysql ${MYSQL_CONN} --skip-column-names -A | sed 's/$/;/g' > MySQLUserGrants.sql

두 방법 모두 MySQL 보조금의 순수 SQL 덤프를 생성합니다. 새 서버에서 스크립트를 실행하기 만하면됩니다.

mysql -uroot -p -A < MySQLUserGrants.sql

시도 해봐 !!!


1
pt-show-grants는 정확하게 당신이 원하는 것입니다, 그것은 훌륭하게 작동합니다.
Glenn Plas

Percona는 순수한 굉장함입니다.
sjas

7
그러나 2 번 답변은 훌륭하며 추가 소프트웨어 없이도 작동합니다!
sjas

14

Richard Bronosky의 답변은 매우 유용했습니다. 많은 감사합니다 !!!

여기에 유용한 작은 변형이 있습니다. phpmyadmin을 실행하는 두 개의 Ubuntu 설치간에 사용자를 전송하는 데 도움이됩니다. root, phpmyadmin 및 debian-sys-maint를 제외한 모든 사용자에게 권한을 덤프하십시오. 그런 다음 코드는

mygrants()
{
mysql -B -N $@ -e "SELECT DISTINCT CONCAT(
'SHOW GRANTS FOR ''', user, '''@''', host, ''';'
) AS query FROM mysql.user WHERE user NOT IN ('root','phpmyadmin','debian-sys-maint')"  | \
mysql $@ | \
sed 's/\(GRANT .*\)/\1;/;s/^\(Grants for .*\)/## \1 ##/;/##/{x;p;x;}'
}

2
내 예제를 보면 grep rails_admin모든 엣지 케이스에 대해 특별한 기능을 수행하지 않고이를 수행하는 방법을 유추 할 수 있습니다. grep의 "invert-match"옵션을 다음과 같이 사용하십시오 :mygrants --host=prod-db1 --user=admin --password=secret | grep -Ev 'root|phpmyadmin|debian-sys-maint' | mysql --host=staging-db1 --user=admin --password=secret
Bruno Bronosky

7

또는 percona-toolkit (이전 maatkit)을 사용 하고 해당 목적으로 사용 pt-show-grants(또는 mk-show-grants)하십시오. 번거로운 스크립트 및 / 또는 저장 프로 시저가 필요하지 않습니다.


5

'mysql'데이터베이스를 mysqldump하고 새 데이터베이스로 가져올 수 있습니다. flush_privileges 또는 재시작이 필요하며 기존 mysq db를 먼저 백업해야합니다.

기존 권한을 제거하지 않으려면 권한 테이블의 행 (db, columns_priv, host, func 등)을 바꾸지 말고 추가하십시오.


감사합니다 @nedm. dbs를 해제하려고하는 성가신 cPanel 서버에 db 'mysql'이 표시되지 않는 것 같습니다. 그렇지 않으면 귀하의 답변을 테스트하고 확인합니다. 확인하면 다시 확인해 보겠습니다. 감사.
Gareth

불행히도 이해할 만하지 만 공유 데이터베이스에서 사용자가 직접 소유 한 데이터베이스는 액세스 할 수 없습니다.
Dave Cheney

예, 'mysql'에 액세스하지 않으면 사용자 또는 권한과 관련된 작업을 수행하기가 어렵습니다. 명령 줄 액세스 권한이 있습니까? 터미널이나 명령 줄에서 mysqldump를 실행할 수 있습니까 (mysql 쉘에서는 아닙니다)? mysqldump -u username -ppassword mysql> mysqldump.sql
nedm

'root'로 로그인하면 Cpanel WHM에서 db 'mysql'에 액세스 할 수 있습니다. 거기에서 나는 'MySQL을'데이터베이스에 포함 된 권한이 phpMyAdmin을 버전에 액세스 할 수 있습니다
가레스

기존의 mysql 스키마로 병합하면 mysqldump를 통해 mysql 스키마에서 추출 된 데이터는 거의 문제가되지 않습니다. 강제 관계 등으로 복잡한 스키마를 조작하고 있습니다.이 스키마는 실제로 매우 복잡하여이를 처리하기위한 전용 SQL 구문 (GRANT, REVOKE, DROP USER 등)을 만들었습니다. 그러나 추출은 INSERT 문으로 만 구성됩니다. 여기에 문자가 부족합니다. 계속해야합니까?
Bruno Bronosky

4

저장 프로 시저로 수행 할 수도 있습니다.

CREATE PROCEDURE spShowGrants()
    READS SQL DATA
    COMMENT 'Show GRANT statements for users'
BEGIN
    DECLARE v VARCHAR(64) CHARACTER SET utf8;
    DECLARE c CURSOR FOR
    SELECT DISTINCT CONCAT(
        'SHOW GRANTS FOR ', user, '@', host, ';'
    ) AS query FROM mysql.user;
    DECLARE EXIT HANDLER FOR NOT FOUND BEGIN END;  
    OPEN c;
    WHILE TRUE DO
        FETCH c INTO v;
        SET @v = v;
        PREPARE stmt FROM @v;
        EXECUTE stmt;
    END WHILE;
    CLOSE c;
END

그리고 그것을 호출

$ mysql -p -e "CALL spShowGrants" mysql

그런 다음 권한을 백업하기 위해 Richards sed 명령을 통해 출력을 파이프하십시오.


3

@Richard Bronosky의 대답이 정답이지만, 한 서버에서 다른 서버로 데이터베이스 세트를 마이그레이션하려고 시도한 후이 질문에 부딪 쳤으며 솔루션은 훨씬 간단했습니다.

server1$ mysqldump -u root -p --all-databases > dbdump.sql

server2$ mysql -u root -p < dbdump.sql

내가로 로그인 한 경우이 시점에서, 내 모든 데이터를 볼 수 있었다 root, mysql.user테이블 내가 기대 한 그 모든 것을 가지고,하지만 난 다른 사용자의로 로그온 할 수 없습니다 내가 재해야 할 것 가정이 질문에 발견 GRANT진술을 발행하십시오 .

그러나 mysql.*테이블 의 업데이트 된 권한을 적용하려면 mysql 서버를 다시 시작해야한다는 것이 밝혀졌습니다 .

server2$ sudo restart mysql

다른 사람이 간단한 작업을 수행하는 데 도움이되기를 바랍니다.


아, 그리고 기존 데이터베이스 / 사용자가있는 서버에 덤프를 병합하려고하지 않았다는 점에서 OP와 상황이 약간 다릅니다.
Tom

2
실제로 '권한을 업데이트'하기 위해 MySQLd를 다시 시작할 필요는 없습니다. MySQL 명령 'flush privileges;'를 사용하여 수행 할 수 있습니다.
CloudWeavers

이 방법의 문제점은 소스 및 대상 MySQL 버전이 모두 동일한 경우에만 작동한다는 것입니다. 그렇지 않으면 소스 mysql.user 테이블에 대상 mysql.user 테이블과 다른 열이 있으므로 문제가 발생할 수 있습니다.
Mitar

3

PHP 스크립트는 어떻습니까? :)

이 스크립트에서 소스를 보면 모든 권한이 나열됩니다.

//connect
mysql_select_db("mysql", mysql_connect("localhost","root",""));

//create grants select statements
$rs = mysql_query("SELECT DISTINCT CONCAT('SHOW GRANTS FOR ''', user, '''@''', host, ''';') AS query FROM user");

//iterate through grants
while ($row=mysql_fetch_array($rs)) {
    //run grant query
    $rs2 = mysql_query($row['query']);
    //iterate through results
    while($row2 = mysql_fetch_array($rs2)){
        //print results
        echo $row2[0] . ";\n\n";
    }
}

2

다음 코드를 사용하여 쉘 스크립트 파일을 작성하십시오.

##############################################삼
echo "SELECT DISTINCT CONCAT (\"show grants for '\", user, \"'@'\", host, \"';\") AS query FROM mysql.user; " >   script.sql    
echo "*** You will be asked to enter the root password twice ******"    
mysql -u root -p  < script.sql > output.sql ;    
cat output.sql | grep show > output1.sql  ; rm output.sql -f ; 
mysql -u root -p  < output1.sql > output.sql ;
clear
echo "-----Exported Grants-----"    
cat  output.sql ; rm  output.sql   output1.sql -f    
echo "-------------------------"
rm  script.sql -f
#

**** 다음과 같이 쉘에서 실행하십시오 : 루트 암호를 두 번 입력하라는 메시지가 표시되면 GRANTS SQL이 화면에 표시됩니다. ****


0

하나의 라이너는 굉장한 것과 거의 동일합니다 pt-show-grants.

mysql --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') FROM mysql.user WHERE user<>''" | mysql --skip-column-names -A | sed 's/$/;/g'

유닉스 도구만을 기반으로하며 추가 소프트웨어가 필요하지 않습니다.

bash 쉘 내에서 실행하면 사용자 .my.cnf의 비밀번호를 mysql root읽을 수 있는 작업이 있다고 가정 합니다 .


반년 후 반년이 지난 후 @rolandomysqldba의 게시물의 절반을 복제했습니다.
sjas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.