728x90

데이터베이스 마이그레이션은 참 번거로운 작업입니다.
상황에 따라서는 메인터넌스를 걸고 서비스를 잠시 중단해야 할 수도 있고
그걸 원하지 않는다면 dual-write 등의 수단을 통해
데이터베이스를 싱크업 하는 과정을 수행해야만 합니다. 

마이그레이션이 이번 글의 주제는 아닙니다.
다만 마이그레이션이 필요하지만 메인터넌스 윈도우를 만들고 싶지 않아 
데이터베이스를 매뉴얼하게 옮기는 것을 고민하다
문득 <데이터베이스의 모든 테이블 레코드 갯수를 한번에 뽑고 싶다>는
자체 요구사항이 생겨 확인한 내용을 정리해 봅니다.

데이터베이스의 모든 레코드 갯수 쿼리

데이터베이스에 있는 모든 테이블의 레코드 갯수를 카운트 하는 것은
아래의 쿼리를 통해 수행할 수 있습니다. 

SELECT SUM(TABLE_ROWS) 
  FROM INFORMATION_SCHEMA.TABLES 
 WHERE TABLE_SCHEMA = '##데이터베이스이름##';

 

모든 테이블 단위로 레코드 갯수 그룹화하는 쿼리

데이터베이스 내에 테이블이 많다면
각 테이블별로 레코드 갯수를 카운트 하고 싶을지도 모릅니다. 
INFORMATION_SCHEMA.TABLES 가 갖고 있는
몇 가지 컬럼을 활용해서 Group By 하면 쉽게 쿼리할 수 있습니다. 

SELECT TABLE_NAME, TABLE_ROWS
  FROM INFORMATION_SCHEMA.TABLES 
 WHERE TABLE_SCHEMA = '##데이터베이스이름##';

 

자, 이제 마이그레이션을....다시... ㅜㅜ

728x90
728x90

새로운 개발 장비가 생기면 이전에 사용하던 장비의 환경과 동일하게 준비하는 것이 은근 번거롭습니다. 한동안 손대지 않고 있던 파이썬 Python 장고 Django 프레임웍으로 개발된 코드를 새 장비에서 다루려다보니 역시나 의존성 문제들이 여러번 발생하고 있습니다.

그 중에서도 최초 환경 설치시에도 겪었던 mysqlclient 패키지 설치 이슈가 있어서 간략하게 정리해봅니다. 한줄 요약을 먼저하자면 Mac OS 환경에서는 homebrew 를 이용해 mysql 을 설치하는 것이 가장 쉽고 빠른 해결 방법입니다. 


개발중인 과제는 requirements.txt 에 필요한 의존성 패키지들이 잘 정리되어 있습니다. virtualenv 를 사용할 수 있는 환경을 만들고 pip install -r requirements.txt 명령을 이용해 패키지를 잘 설치하던 와중에... 떡하니 mysqlclient 패키지 설치가 문제가 발생했습니다.

폴백 fallback 로직에 따라 하위 버전까지 내려가면서 설치 시도를 하느라 실제 터미널 화면에는 휘황찬란한 붉은색의 에러메세지가 도배되었습니다. 에러를 알려주려는 메세지는 여러줄이었지만 핵심을 찝어내면 mysql_config not found 에러가 문제였습니다. 구글링을 조금 해보면 Mac OS 에서는 mysql 설치로 해결하는 것이 정석인듯 합니다. 

Collecting mysqlclient
  Downloading mysqlclient-2.0.3.tar.gz (88 kB)
     |████████████████████████████████| 88 kB 2.6 MB/s 
    ERROR: Command errored out with exit status 1:
    ...
    ...
    Complete output (15 lines):
    /bin/sh: mysql_config: command not found
    /bin/sh: mariadb_config: command not found
    /bin/sh: mysql_config: command not found
    ...
    ...
    OSError: mysql_config not found
    mysql_config --version
    mariadb_config --version
    mysql_config --libs

 

Homebrew 를 이용하여 mysql 을 설치하는 방법은 간단합니다. 사실 mysql 설치 외에도 다른 방법이 있을 거라 생각되지만 (로컬 환경에서 mysql 인스턴스를 띄울 일도 없어서...) 환경을 만들고 코드를 동작시키는 것이 더 급한 관계로 mysql 을 설치했습니다. 

% brew install mysql
==> Downloading https://ghcr.io/v2/homebrew/core/protobuf/manifests/3.15.8
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/protobuf/blobs/sha256:a1615a95bf6f0bd3d9111fd0afa9260373295eadf147c35aef03e31abdbef6bc
==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sha256:a1615a95bf6f0bd3d9111fd0afa9260373295eadf147c35aef03e31abdbef6bc?se=2021-05-18T03%3A15%3A00Z&sig=fpdRcLV73XovJ%2BjHStE98SY%2B9UBYum6GJxr8QQa
######################################################################## 100.0%
...
...
MySQL is configured to only allow connections from localhost by default

To connect run:
    mysql -uroot

To have launchd start mysql now and restart at login:
  brew services start mysql
Or, if you don't want/need a background service you can just run:
  mysql.server start
%

 

mysql 설치가 완료된 후 다시 pip 로 requirements.txt 에 기술된 항목들을 설치 시도해보니 특별히 문제 없이 mysqlclient 가 설치되는 것을 확인할 수 있었습니다. 똑똑한 pip 는 캐시에 저장된 mysqlclient 바이너리를 활용하여 패캐지 설치를 마쳤답니다 :-)

% pip3 install -r requirements.txt
...
...
Collecting mysqlclient
  Using cached mysqlclient-2.0.3.tar.gz (88 kB)
Collecting netifaces
  Downloading netifaces-0.10.9.tar.gz (28 kB)
Collecting cryptography
...
...

 

(업데이트) 트위터로 포스팅이 공유된 후 "왜 PyMySQL과 mysqlclient를 같이 쓰는가?"에 대한 이야기를 들었습니다. 그러고 보니... 왜 두개가 같이 들어가 있는지 생각도 못하고 있었네요. 다행(?)히도 같이 작업하시던 누군가 PyMySQL과 mysqlclient를 같이 시험하다 최종적으로 mysqlclient를 쓰기로 한 것이었습니다. requirements.txt에서 가볍게 삭제~ 

검색을 해보면 python에서 mysql 액세스를 하기 위해 널리 쓰이는게 PyMySQL과 mysqlclient, 그리고 peewee 정도인 것 같습니다. peewee는 ORM의 성격이 강한 것 같고 (써보진 않았습니다) mysqlclient는 C로 개발되어 속도가 빠르다, PyMySQL은 python 으로 만들어졌다 정도의 특징들이 있는 것 같네요!

728x90
728x90

좋은 Practice 는 아니겠지만, 간단한 DB 조회를 위해서 mysql 이 제공하는 CLI 를 이용하는 경우가 다들 있으실 겁니다.

데이터를 조회 및 확인만 화면으로 한다면 특별히 문제 없겠지만 가끔을 엑셀 등의 도구로 데이터를 옮겨야 할 경우가 생기곤 합니다.

mysql CLI 의 기본 쿼리 결과는 결과를 테이블, 레이아웃, 혹은 박싱이라 불리우는 형태로 표현해 줍니다.

보기에는 좋지만 다른 도구에 붙여 넣기에는 영~ 불편한게 사실이죠


보기는 좋지만...


보기 좋은 떡이 먹기 좋다는 옛말이 있지만 이 박스를 좀 없애고 싶은 분들도 많으실겁니다.

박스를 없애려면 mysql CLI 구동시 몇 가지 옵션을 추가해 주셔야 합니다. 


$ mysql -u user_name_place -p -s -r

Enter password:

mysql>

mysql> use sys

mysql> select * from version;

sys_version     mysql_version

2.0.0   8.0.12


-s 옵션을 주면 일단 박스가 사라지긴 합니다. 

하지만 출력되는 데이터에 escape 처리를 하게 되니, 완벽한 RAW 데이터 추출을 위해서는

-s 옵션과 함께 -r 옵션을 주는 것이 좋습니다. 






728x90
728x90

mysql 8.x 이전 버전에서는 발생하는 이슈인지 조사를 해보진 못했습니다만

최소한 mysql 8.x 버전에서는 이 문제가 발생할 수 있는 상태입니다. 


제 경우 Grafana 에서 mysql 데이터 소스를 만들던 도중 에러를 만났고

소개해 드리는 링크에서 나온 것처럼 Go 로 만든 배치 스크립트에서는

동일한 이슈가 생기지 않았습니다.


// 에러메세지

this authentication plugin is not supported


문제는 강화된 보안 체계로 인해 외부 어플리케이션에서 사용되는 mysql 관련 모듈이

mysql 8.x 의 기본 값으로 설정된 패스워드 보안 알고리즘을 맞추지 못해서 발생하는 문제로 보입니다. 


해결 방법은 여러가지가 있지만 mysql 인스턴스 전체에 영향을 주지 않는 방법으로

사용자 단위로 패스워드 보안 정책을 변경하는 것이 가장 좋아 보입니다.


// mysql 8.x 의 기본 사용자 비밀번호 정책

caching_sha2_password


// 이슈 해결을 위한 비밀번호 정책

mysql_native_password



사용자 단위로 이를 적용하기 위해서는 alter user 를 사용하면 됩니다.

에러메세지를 만난 사용자를 대상으로 명령 수행후 에러가 사라진 것을 확인할 수 있으실 겁니다.


mysql> alter user 대상유저@'%' identified with mysql_native_password by '새비밀번호';


# 몇 가지 다른 대안까지 소개되고 있는 글 : https://github.com/go-sql-driver/mysql/issues/785


728x90

+ Recent posts