MySQL Command Line Interface

Sunguck Lee
당근 테크 블로그
10 min readMay 21, 2022

요즘은 세상의 모든 컴퓨터 화면이 그래픽 인터페이스로 바뀐 것 처럼 보입니다. 업무를 하면서도 주변의 컴퓨터를 돌아보면, 까만 색 바탕의 녹색 글자(물론 컬러는 다를 수 있겠지만)는 찾아보기 어렵죠.

누구나 한번쯤은 ASCII art로 터미널 화면을 꾸며 보지 않았을까요 ?

MySQL도 MySQL Workbench나 3rd-party로 제공되는 다양한 형태의 SQL 인터페이스 프로그램들을 제공하고 있는데, 이들 대부분은 그래픽 인터페이스를 기반으로 하고 있습니다. 사용자의 취향에 따라서 차이는 있겠지만, 많은 사용자들이 화면에 많은 기능(버튼과 팝업 메뉴들)들이 한 눈에 보이는 그래픽 기반 인터페이스를 선호하고 있죠.

하지만 누군가는 여전히 텍스트 기반의 명령어 인터페이스(Command line interface)를 더 선호하고, 때로는 그래픽 인터페이스보다 효율적인 업무 환경을 제공한다고 생각합니다. 개인적으로 어떤 DBMS든지 Command Line Interface(CLI)를 선호하는 편인데, MySQL CLI-client는 Oracle이나 PostgreSQL CLI-client에 비해서 불편한 점이 꽤 있는 편이긴 합니다. 오늘은 MySQL CLI-client를 변형하면 어떻게 달라질 수 있는지를 보여 드리려고 해요.

문장의 간결함을 위해서, 이제부터는 높임말은 생략할게요.

MySQL CLI-client 코드는 mysql-src/client 디렉토리에 있는데, MySQL client의 기능 대부분은 mysql-src/client/mysql.cc 파일에 저장되어 있다. MySQL 서버 코드보다는 매우 간단하고 짧은 편이어서, C/C++ 전문가가 아니어도 어렵지 않게 읽고 코드를 고칠 수 있다. MySQL client 코드를 설명하는 것은 너무 지루한 이야기이므로, 여기에서는 미리 추가해 둔 기능들을 어떻게 사용하는지 살펴보고자 한다. 이 예시들이 MySQL client를 직접 개선해서 사용해 볼 수 있는 시작점이 될 수 있기를 기대한다. .

오늘은 아래와 같은 기능들을 MySQL client에 추가해서 사용하는 예시들을 살펴보고자 한다.

  • MySQL client의 프롬프트 내용 추가 및 컬러 변경
  • MySQL client의 단축 명령 추가
  • 파일에 저장된 SQL 실행
  • 특정 케이스에 대한 주의 사항 표시

프롬프트 변경

MySQL client의 프롬프트는 아래와 같이 설정 파일의 prompt 옵션을 통해서 변경할 수 있다. prompt 옵션의 설정 방법은 MySQL 메뉴얼(페이지 하단부)에 자세히 설명되어 있으니, 아래 내용이 잘 이해되지 않는다면 참고하도록 하자.

[mysql]
prompt="\\u@\\h:[\\d] > "

MySQL client의 프롬프트로 설정할 수 있는 값들은 매우 다양하다. 하지만 가끔은 더 새로운 욕심이 생긴다. 대표적으로 Proxy를 이용해서 MySQL 서버에 접속하는 경우, MySQL client는 실제 접속된 서버의 정보를 알아낼 수 없다. 그리고 MySQL 서버는 자신이 프라이머리인지 레플리카인지를 공식적으로 관리하지 않기 때문에, 복제의 역할에 관련된 내용을 프롬프트에 표시해 주지 못한다. MySQL client의 코드를 변경해서, 아래 내용들이 표시되도록 기능을 추가해보았다.

  • \X는 별도의 호스트 목록 파일에서 대상 서버를 찾아서 그 서버의 이름을 표시
  • \Z 는 연결된 서버가 프라이머리인지 레플리카 역할인지를 표시
  • prompt_color_primaryprompt_color_replica 옵션을 이용하여, 프라이머리인 경우와 레플리카인 경우 프롬프트의 컬러를 다르게 표시
[mysql]
prompt="\\u@\\X(\\Z):[\\d] \\R:\\m:\\s\\T>"
prompt_color_primary=magenta
prompt_color_replica=yellow

외부 파일에 설정된 내용(port → server_hostname 맵핑)을 참고해서 해당 서버의 이름을 프롬프트에 표시하고, 그 뒤에는 레플리케이션의 역할을 표시하고 있다. 마지막으로 프라이머리이기 때문에, 프롬프트의 색깔이 붉은 계열의 magenta 로 표시되었다.

MySQL client의 단축 명령

PostgreSQL client 를 사용하면서 느낀 장점 중 하나는 많은 메타 정보 SELECT 문장들이 단축 명령으로 확인이 가능하다는 것이었다. 때로는 단축 명령이 너무 많아서 복잡해 보이기도 하지만, 하루 종일 고생하는 손가락과 빠른 조회를 위해서는 매우 훌륭한 기능임은 확실해 보였다. 그래서 MySQL client에서도 몇 가지 자주 사용하는 조회 SQL을 위한 단축 명령을 사용할 수 있도록 코드를 변경해보았다.

여기에서 구현된 단축 명령은 \\ 로 시작되어야 하며, 그 뒤에 한글자 또는 두글자의 알파벳으로 구성된다. 지원되는 단축 명령의 목록을 확인하고자 한다면, \\ 만 입력하고 엔터를 누르면 볼 수 있도록 해두었다.

단축 명령 목록 확인

아마도 MySQL client를 자주 사용하는 경우, 느끼는 가장 큰 고통은 데이터베이스 목록 조회를 할 때 사용하는 SHOW DATABSAES 명령 타이핑일 것이다. 대부분의 키보드가 왼쪽 손에 몰려있고, 특히 SE 의 순서가 자주 틀린다는 것에 동의할 것이다. 이제 추가해 둔 단축 명령으로 데이터베이스 목록을 쉽게 확인하는 방법을 살펴보자.

\\d 단축 명령으로 SHOW DATABASES 명령이 실행되고, 결과가 출력된 것을 볼 수 있다. “이게 뭐라고?”라고 생각하는 사람도 있겠지만, MySQL client를 하루 종일 사용하는 입장에서는 (주관적인 판단으로) 획기적인 기능이라고 확신한다. 이 이외에도 사용자 목록과 함수나 프로시져 목록 그리고 잠금 대기나 장시간 활성 상태의 트랜잭션 목록 조회 등 자주 사용하는 명령들을 \\ 단축 명령어로 쉽게 실행할 수 있다.

예시된 단축 명령 이외에도 많은 기능들을 추가해두었으므로, 더 많은 예제들이 궁금하다면 여기 링크의 README.md 파일을 참고해보자.

SQL 파일 실행

아마도 MySQL client를 자주 경험해 본 사용자라면, MySQL client의 source 또는 \. 명령이 정확히 이 목적을 위한 기능이라는 것을 기억할 것이다. 그런데 Oracle client를 사용해 본 사용자라면, MySQL client의 source 명령에서는 SQL 파라미터(바인딩 변수) 설정 기능이 누락되어 있다는 것이 얼마나 큰 불편함인지 잘 알고 있을 것이다. 물론 세션 변수를 이용하면 바인딩 변수 역할을 대체할 수 있다. 하지만 세션 변수를 사용하기 위해서는, 파일에 저장된 SQL 문장에서 어떤 세션 변수가 정의되어야 하는지를 모두 기억해야 하며, 더 큰 문제는 세션 변수는 SQL 문장의 특정 위치에는 사용될 수 없다는 것이다. MySQL 8.0.23 client 부터 도입된 Query attributes 기능 또한 이런 문제들을 해결하는데 큰 도움이 되지는 않는 것으로 보인다.

그래서 이런 불편함을 회피하기 위해서, \\x 단축 명령을 이용해서 지정된 디렉토리의 SQL 파일을 실행할 수 있도록 기능을 추가했다. \\x 단축 명령은 아래 디렉토리에서 인자로 명시된 SQL 파일을 찾아서 실행한다.

  1. MYSQL_SCRIPTDIR 환경 변수에 설정된 디렉토리
  2. ~/.mysqlrc/ 디렉토리

MYSQL_SCRIPTDIR 환경 변수가 별도로 설정되지 않으면, ~/.mysqlrc/ 디렉토리에서 SQL 파일을 검색하게 된다. \\x 명령으로 SQL 파일을 실행하는 방법은 다음과 같다. 실행할 SQL 파일의 확장자는 반드시 .sql 이어야 하며, \\x 명령 사용시에는 .sql 확장자를 명시하지 않아야 한다. 이는 단순히 입력의 편의를 위한 것일 뿐, 다른 목적은 없다.

테스트를 위해서 아래 내용의 ~/.mysqlrc/test.sql 파일을 준비하고,

SELECT '#{STRING_VARIABLE}' as string_var LIMIT #{LIMIT_N_ROWS};

MySQL client에서 \\x test 명령을 실행해보자.

\\x test 명령은 ~/.mysqlrc/test.sql 파일을 읽어서 실행하는데, 만약 SQL 문장에 바인딩 변수가 정의되어 있으면, 터미널에 사용자가 변수 값을 입력할 수 있도록 변수명을 표시하고 입력을 기다리게 된다. 위의 예제에서는 2개의 바인딩 변수( #{STRING_VARIABLE}#{LIMIT_N_ROWS})를 입력받아서 쿼리를 실행한 것이다. 예시에서 보인 바와 같이 \\x 명령으로 처리되는 바인딩 변수는 세션 변수 또는 표준 바인딩 변수 형태가 아니기 때문에, 아래 규칙을 준수해서 SQL 파일에 사용되어야 한다.

  • SQL 파라미터는 #{변수명}포맷으로 명시
  • (바인딩 변수의 타입을 인식하지 못하기 때문에) 문자열 타입인 경우 SQL 문장에서 따옴표를 포함해서 '#{STRING_VAR}' 와 같이 사용

참고로, \\x 명령은 배치 형태로 처리되지 않기 때문에, 파일의 모든 내용을 메모리로 읽어 들인 후 실행하기 때문에, source 명령처럼 매우 큰 SQL 파일을 실행하지는 못한다.

특정 케이스에 대한 주의 사항 표시

MySQL 서버를 사용함에 있어서, 각 회사별로 주의해야 하는 사항들이 다양하게 있을 것이다. 예를 들어서 특정 시스템 변수가 활성화된 경우 경고 메시지를 출력하거나, Production DBMS 서버는 경고 메시지를 표시한다는 등의 요건들이 있을 수 있다. 여기에서는 간단한 예시를 위해서, MySQL 서버의 innodb_adaptive_hash_index가 활성화된 경우 로그인 시점에 경고 메시지를 출력하도록 코드를 추가해보았다.

여기에서 살펴본 것은 간단한 예시일 뿐이며, 각 회사 또는 DBA별로 필요로 하는 경고 메시지를 넣어두면 실수를 최소화할 수 있지 않을까 생각된다. 조금만 더 신경쓰면, 경고 메시지의 색깔을 조정해서 더 눈의 띄도록 만들 수도 있을 것이다.

오늘 예시에 사용된 MySQL client 소스 코드는 아래 github에서 다운로드할 수 있습니다.

얼마나 많은 MySQL 사용자들이 Command Line Interface를 사용하고 있을지는 모르겠지만, 오늘 글이 많은 사용자들에게 힘들고 지루한 일상의 소소한 재미꺼리가 되고, 나아가서는 MySQL client를 사랑하시는 분들의 손가락 관절 노화방지에도 도움이 될 수 있기를 기대합니다.

이번 이야기도 재미있게 읽으셨다면, 그리고 더 많은 것들을 경험하고 싶으시다면, Real MySQL 오픈 챗 참여 또는 당근 마켓 개발자와 DBA로 지원해주세요.

--

--