MySQL : 사용자가 있는지 확인하고 삭제


84

MySQL 사용자가 존재하는지 확인하는 표준 방법은 없으며이를 기반으로 삭제합니다. 이에 대한 해결 방법이 있습니까?

편집 : 오류 던지고없이이를 실행하는 직선 방법이 필요
예를

DROP USER test@localhost; :    

1
MySQL 사용자를 의미합니까? 아니면 MySQL의 테이블에 저장하는 사용자 레코드입니까?
Jason Cohen

MariaDB에이 기능이있는 것 같습니다. mariadb.com/kb/en/mariadb/drop-user
Limited Atonement

1
향후 독자를 위해 : MySQL 5.7에는 'DROP USER IF EXISTS'기능이 있습니다. stackoverflow.com/questions/598190/…
Andrei Epure

1
@AndreiEpure이 답으로 답할 수 있다면 올바른 것으로 표시하겠습니다.
Cherian

답변:



87

이것은 나를 위해 일했습니다.

GRANT USAGE ON *.* TO 'username'@'localhost';
DROP USER 'username'@'localhost';

사용자가 아직 존재하지 않는 경우 사용자를 생성 한 다음 (무해한 권한을 부여) 어느 쪽이든 삭제합니다. 여기에서 해결책을 찾았습니다 : http://bugs.mysql.com/bug.php?id=19166

업데이트 : @Hao는 추가를 권장합니다IDENTIFIED BY . @andreb (주석에서)는 NO_AUTO_CREATE_USER.


5
실제로 MySQL grant 매뉴얼 페이지 에서 다음과 같이 표시됩니다. USAGE : "권한 없음"의 동의어
stivlo

6
이것은 더 이상 선택 사항이 아닙니다. :( 현재 버전의 MySQL은 더 이상 GRANT 문에 대한 새 사용자를 생성하지 않습니다. 그들이 추가 한 "기능"이었습니다.;) Cherian의 옵션이 현재 작동하는 유일한 옵션 인 것 같습니다.
GazB 2011

1
@Zasurus. dev.mysql.com/doc/refman/5.1/en/grant.html (또한 5.5 및 5.6)은 당신이 틀렸다는 것을 암시하는 것 같습니다. "자동 사용자 생성 없음"옵션이 있습니다. 매뉴얼을 오해하지 않는 한 그랜트가 존재하지 않으면 사용자가 생성된다는 의미입니다.
andreb

@andreb 아마도 "NO_AUTO_CREATE_USER"옵션이이 옵션을 시도했을 때 또는 기본적으로 켜져 있었을 것입니다 (변경하지 않은 것처럼). 시간이 있으면이 옵션을 끄고 다시 시도합니다. 이 옵션에 대한 몇 가지 공개 된 버그 보고서가 있습니다. 그중 하나가 문제 일 수도 있습니다. :)
GazB

@Hao의 답변도 참조하십시오. IDENTIFIED BY실제로 작동하도록하려면이 필요했습니다 .
Matthew

14

phyzome의 답변 (가장 많이 득표 한 답변)에 대해, 승인 내역서 끝에 "식별자"를 입력하면 사용자가 자동으로 생성되는 것 같습니다. 그러나 그렇지 않으면 사용자가 생성되지 않습니다. 다음 코드는 저에게 효과적입니다.

GRANT USAGE ON *.* TO 'username'@'localhost' IDENTIFIED BY 'password';
DROP USER 'username'@'localhost';

도움이 되었기를 바랍니다.


나는 '암호'로 식별되지 않은 오래된 스크립트를 가지고 있습니다. 5.6에서 작동했던 부분. 그러나 5.7에서는 그렇지 않았습니다. IDENTIFIED BY 'password'부분을 추가하면 나에게 트릭이 생겼습니다.
joensson

13

MySQL 포럼 중 하나에서 이에 대한 답을 찾았습니다. 사용자를 삭제하려면 절차를 사용해야합니다.

여기서 사용자는 "test"이고 "databaseName"은 데이터베이스 이름입니다.


SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ANSI';
USE databaseName ;
DROP PROCEDURE IF EXISTS databaseName.drop_user_if_exists ;
DELIMITER $$
CREATE PROCEDURE databaseName.drop_user_if_exists()
BEGIN
  DECLARE foo BIGINT DEFAULT 0 ;
  SELECT COUNT(*)
  INTO foo
    FROM mysql.user
      WHERE User = 'test' and  Host = 'localhost';
   IF foo > 0 THEN
         DROP USER 'test'@'localhost' ;
  END IF;
END ;$$
DELIMITER ;
CALL databaseName.drop_user_if_exists() ;
DROP PROCEDURE IF EXISTS databaseName.drop_users_if_exists ;
SET SQL_MODE=@OLD_SQL_MODE ;

CREATE USER 'test'@'localhost' IDENTIFIED BY 'a'; GRANT ALL PRIVILEGES ON databaseName.* TO 'test'@'localhost' WITH GRANT OPTION


@Cherian에게 감사드립니다. 이것이 2017 년에도 여전히 최선의 방법인지 모르겠지만 적어도 앞으로 나아가는 방법입니다! 나는이 ... 열심히 여전히 믿을 수 없어
JMAC

참고로 항상 소스의 URL을 포함해야합니다 (예 : mysql 양식 중 하나에서 답변을 찾았습니다 . 또는 mysql 양식 (출처 여기) 중 하나에서)

4
DROP USER IF EXISTS 'user'@'localhost' ;

Maria DB에서 오류를 일으키지 않고 나를 위해 작동합니다.


2
MySQL 5.7 이상에서는 물론입니다. ... 행운, 여기서 사용하는 최신 버전은 5.5입니다.
tetsujin

4

업데이트 : MySQL 5.7부터는 DROP USER IF EXISTS문 을 사용할 수 있습니다 . 참조 : https://dev.mysql.com/doc/refman/5.7/en/drop-user.html

통사론: DROP USER [IF EXISTS] user [, user] ...

예: DROP USER IF EXISTS 'jeffrey'@'localhost';

참고로 (이전 버전의 MySQL의 경우) 더 나은 솔루션입니다 ... !!!

다음 SP는 다음 'tempuser'@'%'을 실행하여 사용자를 제거하는 데 도움이됩니다.CALL DropUserIfExistsAdvanced('tempuser', '%');

이름이 지정된 모든 사용자 'tempuser'(예 'tempuser'@'%': 'tempuser'@'localhost''tempuser'@'192.168.1.101') 를 제거 하려면 SP를 실행합니다. CALL DropUserIfExistsAdvanced('tempuser', NULL);이렇게하면 이름이 tempuser!!! 인 모든 사용자가 삭제됩니다. 진지하게 ...

이제 언급 된 SP를 살펴보십시오 DropUserIfExistsAdvanced.

DELIMITER $$

DROP PROCEDURE IF EXISTS `DropUserIfExistsAdvanced`$$

CREATE DEFINER=`root`@`localhost` PROCEDURE `DropUserIfExistsAdvanced`(
    MyUserName VARCHAR(100)
    , MyHostName VARCHAR(100)
)
BEGIN
DECLARE pDone INT DEFAULT 0;
DECLARE mUser VARCHAR(100);
DECLARE mHost VARCHAR(100);
DECLARE recUserCursor CURSOR FOR
    SELECT `User`, `Host` FROM `mysql`.`user` WHERE `User` = MyUserName;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET pDone = 1;

IF (MyHostName IS NOT NULL) THEN
    -- 'username'@'hostname' exists
    IF (EXISTS(SELECT NULL FROM `mysql`.`user` WHERE `User` = MyUserName AND `Host` = MyHostName)) THEN
        SET @SQL = (SELECT mResult FROM (SELECT GROUP_CONCAT("DROP USER ", "'", MyUserName, "'@'", MyHostName, "'") AS mResult) AS Q LIMIT 1);
        PREPARE STMT FROM @SQL;
        EXECUTE STMT;
        DEALLOCATE PREPARE STMT;
    END IF;
ELSE
    -- check whether MyUserName exists (MyUserName@'%' , MyUserName@'localhost' etc)
    OPEN recUserCursor;
    REPEAT
        FETCH recUserCursor INTO mUser, mHost;
        IF NOT pDone THEN
            SET @SQL = (SELECT mResult FROM (SELECT GROUP_CONCAT("DROP USER ", "'", mUser, "'@'", mHost, "'") AS mResult) AS Q LIMIT 1);
            PREPARE STMT FROM @SQL;
            EXECUTE STMT;
            DEALLOCATE PREPARE STMT;
        END IF;
    UNTIL pDone END REPEAT;
END IF;
FLUSH PRIVILEGES;
END$$

DELIMITER ;

용법:

CALL DropUserIfExistsAdvanced('tempuser', '%'); 사용자 제거 'tempuser'@'%'

CALL DropUserIfExistsAdvanced('tempuser', '192.168.1.101'); 사용자 제거 'tempuser'@'192.168.1.101'

CALL DropUserIfExistsAdvanced('tempuser', NULL);이름이 지정된 모든 사용자 제거 'tempuser'(예 : 'tempuser'@'%', 'tempuser'@'localhost''tempuser'@'192.168.1.101')


3

음 ... 왜 모든 합병증과 속임수?

대신 DROP USER를 사용합니다 ... mysql.user 테이블에서 사용자를 삭제 한 다음 (사용자가 존재하지 않는 경우 오류가 발생하지 않음) 권한을 플러시하여 변경 사항을 적용 할 수 있습니다.

DELETE FROM mysql.user WHERE User = 'SomeUser' AND Host = 'localhost';
FLUSH PRIVILEGES;

-업데이트-

내가 틀렸어. 그렇게 사용자를 삭제하는 것은 안전하지 않습니다. DROP USER를 사용해야합니다. 부여 (내가 사용하는 옵션)를 통해 사용자를 자동으로 생성하지 않도록 mysql 옵션을 설정할 수 있으므로 여전히 그 트릭을 권장하지 않습니다. 저에게 적합한 저장 프로 시저의 스 니펫은 다음과 같습니다.

DECLARE userCount INT DEFAULT 0;
SELECT COUNT(*) INTO userCount FROM mysql.user WHERE User = userName AND Host='localhost';
IF userCount > 0 THEN
    SET @S=CONCAT("DROP USER ", userName, "@localhost" );
    PREPARE stmt FROM @S;
    EXECUTE stmt;
    SELECT CONCAT("DROPPED PRE-EXISTING USER: ", userName, "@localhost" ) as info;
END IF;
FLUSH PRIVILEGES;

"안전하지 않은"이유를 공유하십시오 ...? 어떤면에서 누구에게 안전합니까?
dagelf

글쎄, 내가 1 년 이상 전에 이것을 게시했기 때문에 나는 내가 언급 한 것을 100 % 기억한다고 주장하지 않을 것이다. 나는 그것이 신뢰성이 시스템에서 사용자를 완전히 제거하지 않는다는 것을 의미한다고 확신합니다. DROP USER는 mysql.user 테이블에서 행을 제거하는 것 이상을 수행한다고 생각합니다. 죄송합니다. 지금 세부 정보가 무엇인지 생각할 수 없습니다.
BuvinJ

권한 레코드가 제거되지 않고 "분리 된"상태가된다고 생각한다면? (설정에 따라?)
BuvinJ

2

@Cherian의 답변과 관련하여 다음 줄을 제거 할 수 있습니다.

SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ANSI';
...
SET SQL_MODE=@OLD_SQL_MODE;
...

이것은 5.1.23 이전의 버그였습니다. 해당 버전 이후에는 더 이상 필요하지 않습니다. 따라서 복사 / 붙여 넣기의 편의를 위해 위의 행을 제거한 것과 동일합니다. 다시 말하지만, 예를 들어 "test"는 사용자이고 "databaseName"은 데이터베이스입니다. 그리고 이것은 이 버그 에서 나왔습니다 .

DROP PROCEDURE IF EXISTS databaseName.drop_user_if_exists ;
DELIMITER $$
CREATE PROCEDURE databaseName.drop_user_if_exists()
BEGIN
  DECLARE foo BIGINT DEFAULT 0 ;
  SELECT COUNT(*)
  INTO foo
    FROM mysql.user
      WHERE User = 'test' and  Host = 'localhost';
   IF foo > 0 THEN
         DROP USER 'test'@'localhost' ;
  END IF;
END ;$$
DELIMITER ;
CALL databaseName.drop_user_if_exists() ;
DROP PROCEDURE IF EXISTS databaseName.drop_users_if_exists ;

CREATE USER 'test'@'localhost' IDENTIFIED BY 'a';
GRANT ALL PRIVILEGES  ON databaseName.* TO 'test'@'localhost'
 WITH GRANT OPTION

2

나는 Cherian의 대답에서 영감을 얻은이 절차를 작성했습니다. 차이점은 내 버전에서는 사용자 이름이 프로 시저의 인수 (하드 코딩되지 않음)라는 것입니다. 또한 사용자를 삭제 한 후 필요한 FLUSH PRIVILEGES를 많이 수행하고 있습니다.

DROP PROCEDURE IF EXISTS DropUserIfExists;
DELIMITER $$
CREATE PROCEDURE DropUserIfExists(MyUserName VARCHAR(100))
BEGIN
  DECLARE foo BIGINT DEFAULT 0 ;
  SELECT COUNT(*)
  INTO foo
    FROM mysql.user
      WHERE User = MyUserName ;
   IF foo > 0 THEN
         SET @A = (SELECT Result FROM (SELECT GROUP_CONCAT("DROP USER"," ",MyUserName,"@'%'") AS Result) AS Q LIMIT 1);
         PREPARE STMT FROM @A;
         EXECUTE STMT;
         FLUSH PRIVILEGES;
   END IF;
END ;$$
DELIMITER ;

또한이 코드를 CodeReview 웹 사이트 ( /codereview/15716/mysql-drop-user-if-exists ) 에 게시했습니다.


2
DROP USER 'user'@'localhost';

위의 명령은 데이터베이스에서 사용자를 삭제하지만 동일한 사용자가 이미 데이터베이스를 사용하고 있는지 확인하는 것이 중요 합니다. 해당 세션은 사용자가 해당 세션을 닫을 때까지 종료되지 않습니다. 삭제 된 사용자는 여전히 데이터베이스에 액세스하고 모든 작업을 수행한다는 점에 유의해야합니다. 사용자를 삭제해도 현재 사용자 세션은 삭제되지 않습니다.


0

phyzome의 답변 (지금 당장 작동하지 않음)과 andreb의 주석 (그 이유를 설명합니다)을 결합하면 NO_AUTO_CREATE_USER 모드가 활성화되어 있으면 일시적으로 비활성화되는이 작동하는 코드가 생겼습니다.

set @mode = @@SESSION.sql_mode;
set session sql_mode = replace(replace(@mode, 'NO_AUTO_CREATE_USER', ''), ',,', ',');
grant usage on *.* to 'myuser'@'%';
set session sql_mode = @mode;
drop user 'myuser'@'%';

0

터미널에서 :

sudo mysql -u root -p

비밀번호를 입력하세요.

select user from mysql.user;

이제 사용자 'the_username'을 삭제하십시오.

DROP USER the_unername;

'the_username'을 삭제할 사용자로 바꿉니다.


-1

학생들이 많이 일하는 학교 서버가있는 경우. 다음과 같이 엉망을 정리할 수 있습니다.

delete from user where User != 'root' and User != 'admin';
delete from db where User != 'root' and User != 'admin';

delete from tables_priv;
delete from columns_priv;

flush privileges;

-6

테이블에서 드롭이있는 경우 삭제하려는 경우 다음과 같은 DELETE명령을 사용할 수 있습니다 .

 DELETE FROM users WHERE user_login = 'foobar'

일치하는 행이 없으면 오류가 아닙니다.


2
OP는 실제 데이터베이스 사용자를 의미한다고 생각합니다.
Tomalak

6
이것은 가장 간단한 솔루션 IMO입니다. 그냥 올바른 SQL이 필요합니다 : mysql 데이터베이스에서 user는 어디에서 삭제 사용자 = '는 foobar'
존 릭스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.