반응형

원격 mysql 서버에 있는 DB의 스키마 작성 쿼리만 얻고 싶을 때?

 

mysqldump --no-data -h [서버IP] -P [포트] -u [사용자] -p [DB명]

  • 옵션 대문자 P와 소문자 p를 헛갈리지 않도록 주의!
  • 보통 mysql 디폴트 포트는 3306 이지만 관리자가 변경할 수 도 있다. 
  • --no-data 옵션으로 데이터는 받지 않고, 스키마만 받을 수 있다. (create table 만 나옴)
  • -p 옵션은 password를 프롬프트로 입력받겠다는 의미이다. -p를 생략하면 패스워드 없이 인증하려고 시도하여 인증실패 날 수 있다. 프롬프트로 패스워드를 받지 않고 커맨드에 패스워드를 직접 넣으려면 -p[패스워드]  이렇게 공백없이 붙여쓴다.   -p 옵션뒤에 공백을 넣고 패스워드를 넣으면  프롬프트로 패스워드 넣으라고 나오고, 뒤에 나온 스트링을 DB명으로 인식하여 찾게 된다.

 

mysql 클라이언트 옵션도 동일하다..

  • mysql  -h [서버IP] -P [포트] -u [사용자] -p
  • mysql  -h [서버IP] -P [포트] -u [사용자] -p[패스워드]
  • mysql  -h [서버IP] -P [포트] -u [사용자] -p [DB명]
  • mysql  -h [서버IP] -P [포트] -u [사용자] -p[패스워드] [DB명]

( -h 옵션 생략시 로컬 호스트 , -P 생략시 3306, -p 생략시 암호없음)

 

반응형
mariadb_10.4_setup

MariaDB 10.4 install / CentOS 7

CentOS 7.9에서 mariaDB 10.4 설치하다 디스크 공간 문제를 고려하여 경로 변경하는 중 계속된 실패로 삽질을 한 참 하였다.

  • 일단 전에 설치된 DB를 지우고 시작.
// 서비스 중지
$systemctl stop mariadb

[패키지 삭제]
$yum remove Maria*

// 전에 설치한 디폴트 경로
$rm -rf /var/lib/mysql

패키지 다운로드 및 기본 설치

yum으로 설치

// MariaDB yum repo 등록
$ vi /etc/yum.repos.d/MariaDB.repo

아래의 내용을 작성한다.

[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.4/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
// MariaDB 설치
$ yum install MariaDB

// 설치된 버전 확인
$ rpm -qa | grep MariaDB
MariaDB-compat-10.4.17-1.el7.centos.x86_64
MariaDB-common-10.4.17-1.el7.centos.x86_64
MariaDB-server-10.4.17-1.el7.centos.x86_64
MariaDB-client-10.4.17-1.el7.centos.x86_64
또는
$ yum list installed Maria*
Installed Packages
MariaDB-client.x86_64                                10.4.17-1.el7.centos                                @mariadb
MariaDB-common.x86_64                                10.4.17-1.el7.centos                                @mariadb
MariaDB-compat.x86_64                                10.4.17-1.el7.centos                                @mariadb
MariaDB-server.x86_64                                10.4.17-1.el7.centos                                @mariadb

// 버전 확인
$ mariadb --version
mariadb  Ver 15.1 Distrib 10.4.17-MariaDB, for Linux (x86_64) using readline 5.1

기본적으로 /var/lib/mysql에 설치된다.

  • 서비스 실행 및 암호 설정
// mariadb 실행
$ systemctl start mariadb

// 패스워드 설정
$ /usr/bin/mysqladmin -u root password '패스워드'

// 포트 확인
$ netstat -anp | grep 3306
tcp6       0      0 :::3306                 :::*                    LISTEN      102252/mysqld
  • DB 생성 및 초기화 / 사용자 생성
$ mysql -u root -p
> use mysql ;

[사용자 추가]
create user 'crazyj'@'%' identified by 'crazyj00.';
create user 'crazyj'@'localhost' identified by 'crazyj00.';
flush privileges ;

[DB생성]
create database CRAZYJ_DB ;
grant all privileges on CRAZYJ_DB.* to 'crazyj'@'%';
grant all privileges on CRAZYJ_DB.* to 'crazyj'@'localhost';
flush privileges ;


[사용자 패스워드 변경]
ALTER user 'crazyj'@'localhost' IDENTIFIED WITH mysql_native_password BY '새패스워드';
또는 아래와 같이 설정
ALTER user 'crazyj'@'localhost' IDENTIFIED BY '새패스워드';
ALTER user 'crazyj'@'%' IDENTIFIED BY '새패스워드';
flush privileges ;

여기서 기본 경로가 /var/lib/mysql 인데 추후 디스크 공간을 고려하면 다른 파티션으로 옮기고 싶어졌다.
여기서 문제가 시작됨…

데이터 경로 위치 변경

쉽게 생각하면… DB 서비스 중지하고,
/var/lib/mysql 폴더를 용량큰 파티션으로 이동하고
기존 경로를 링크를 걸어주면 끝.
이라고 생각하지만, 여러가지 원인으로 실패할 수 있다.

결론부터 말하면

  1. selinux (접근통제)도 off 해줘야 한다.
  2. mariadb 기본설정에서 /root 나 /home 경로로 이동을 막고 있다.
    설정을 바꾸면 해결됨.
  • selinux off
# getenforce
Enforcing
# setenforce 0
# getenforce
Permissive
#
#vi /etc/selinux/config
--------------
#SELINUX=enforcing
SELINUX=disabled
------------
  • mariadb 서비스 설정 변경
$ systemctl stop mariadb
$ vi /usr/lib/systemd/system/mariadb.service
--------------------
# Prevent accessing /home, /root and /run/user
#ProtectHome=true
ProtectHome=false
------------------------
  • DB 링크 설정하고 서비스 시작.
$ mv /var/lib/mysql /home/mysql
$ ln -s /home/mysql /var/lib/mysql

$ systemctl start mariadb

끝.

참고) 아래는 시도 과정…

아예 처음부터 새로 만들자. 디폴트 경로 변경
$ vi /etc/my.cnf.d/server.cnf
아래 섹션에 추가
------------------------
[mysqld]
datadir=/home/data/mysql
socket=/home/data/mysql/mysql.sock
-----------------

$ vi /etc/my.cnf.d/mysql-clients.cnf
아래를 추가 (client 섹션이 없어서 추가)
-----------------
[client]
socket=/home/data/mysql/mysql.sock
----------------

$ cd /bin
$ mariadb-install-db --user=mysql
위 설정파일에서 지정된 경로에서 초기화됨!!!! 
(--user 옵션을 생략하면 root 계정으로 생성됨)

위와 같이 하면 되야 되는데… 서비스 실행시 그래도 에러발생???

  • centOS7의 selinux 기본 정책으로 실패???

  • selinux 관련 설정 변경

$ yum install policycoreutils-python
  
$ ls -lZ /var/lib/mysql
$ cp -rf /var/lib/mysql /home/data/mysql
$ chown -R mysql:mysql /home/data/mysql
$ ls -lZ /home/data/mysql

$ vi my.cnf
datadir=/home/data/mysql

$ semanage fcontext -a -t mysqld_db_t "/home/data/mysql(/.*)?"

$ grep -i mysql /etc/selinux/targeted/contexts/files/file_contexts.local

$ restorecon -R -v /home/data/mysql

$ ls -lZ /home/data/mysql
-----------------------------------
위와 같이 했는데도 결국 안되서 selinux 옵션을 끄기로...

# getenforce
Enforcing
# setenforce 0
# getenforce
Permissive
#
#vi /etc/selinux/config
--------------
#SELINUX=enforcing
SELINUX=disabled
------------

위와 같이 해도 selinux를 off했음에도 실패했음.

원인은… 기본적으로 centos에서 mariadb는 /home, /root 경로를 사용할 수 없다나…
아니, 이런 설정도 있었나??? 헐… 삽질만…

데이터 폴더 이동 방법 찾던 중 발견.

$ systemctl stop mysql
$ mkdir -p /home/data/mysql

$ cp -rf /var/lib/mysql /home/data/mysql
$ chown -R mysql:mysql /home/data/mysql
(나중에 정상작동 확인후, 기존data인 /var/lib/mysql은 삭제)

==================> 이 문제였음. <===================
$ vi /usr/lib/systemd/system/mariadb.service
# Prevent accessing /home, /root and /run/user
#ProtectHome=true
ProtectHome=false
==================> 이 문제였음. <===================

서비스 시작
$ systemctl start mysql

Author: crazyj7@gmail.com

반응형
mysql_setup

MySQL 5.7

타임존 설정

타임존 선택 수동으로 설정하는 방식

ls /usr/share/zoneinfo
여기에서 원하는 지역을 디렉터리 구조 내부를 탐색하여 찾는다.
ls /usr/share/zoneinfo/Asia/Seoul

현재설정
$ ll /etc/localtime
/etc/localtime -> /usr/share/zoneinfo/America/New_York
$ date
Thu Nov 7 20:48:33 EST 2019

다음과 같이 변경
$ sudo ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
$ date
Fri Nov 8 10:55:06 KST 2019

사실 타임존 선택은 더 간단하게 “tzselect” 커맨드로 하면 메뉴를 골라 쉽게 설정할 수 도 있다.

$ tzselect

시간 동기화

시간이 틀리면 여러가지 문제가 발생하니 먼저 시간을 동기화하자.

sudo apt-get install ntp

vi /etc/ntp/conf
server 1.kr.pool.ntp.org
server 1.asia.pool.ntp.org
server time.bora.net

sudo service ntp restart
sudo ntpq -p

설치 (Ubuntu 기준)

-기존 설치된 것 삭제

apt list | grep mysql-server
버전 확인
sudo apt-get purge mysql-server
sudo apt-get purge mysql-common

설치 데이터 삭제
아래 경로 반드시 확인 필요!
rm -rf /var/log/mysql
rm -rf /var/log/mysql.*
rm -rf /var/lib/mysql
rm -rf /etc/mysql
  • 패키지 검색

  • sudo apt-get update

  • sudo apt-cache search mysql-server
    image

  • 설치

  • sudo apt-get install mysql-server-5.7
    image

$ mysql --version
5.7.27
$ vi /etc/mysql/mysql.conf.d/mysqld.cnf
port 번호 변경 (옵션)
$ service mysql restart

관리자 패스워드 설정

수동으로 패스워드 설정 방법

루트로 mysql을 실행한다.
$ sudo mysql -u root 
패스워드 없이 로그인 됨.
> alter user 'root'@'localhost' identified with mysql_native_password by '패스워드';
> flush privileges ;
> exit
$ service mysql restart

일반계정으로 전환하여 로그인 (로컬)
$ mysql -u root -p

간단하게 커맨드로 설정하는 방법

루트로 로그인하여
$ mysqladmin -u root -p password

계정 생성

로컬 접속

> create database test character set utf8 collate utf8_bin ;  # test DB를 만들어서 아래 권한 부여 (옵션)

> use mysql ;
> insert into user(host, user, authentication_string, ssl_cipher,
 x509_issuer, x509_subject) 
 values('localhost', '계정', password('패스워드'), '', '', ''); 
> flush privileges ;
> grant all privileges on DB명.* to 계정@localhost;
> flush privileges ;

빈 값 필드들을 빼보니 쿼리가 실패하였다. grant전에 flush를 안해주면 쿼리가 실패한다. 위에 나온대로 하는 게 좋다.

원격 접속

> 위 로컬 접속에서 localhost를 %로만 바꿔준다. 

더 간단한 방법

> craete user '계정'@'localhost' identified by '패스워드' 
   password expire never ;
> grant all privileges on DB명.* to 계정@localhost;

Author: crazyj7@gmail.com

반응형
mysql query

MySQL Query

Select

두 개의 테이블(또는 Self Table)에서 다른 값 찾기

TABLEA 테이블에서 키가 COMPARE_ID이고, F98 필드에 대해서 같은 테이블의 같은 키, 같은 필드의 필드값이 다른 것을 찾는 쿼리
(두 개의 테이블로 할 경우는 테이블 명과 where 조건절만 수정하면 된다.)
비교할 대상의 테이블 두 개를 UNION해서 같은 키 에 대해 정렬하고 그룹별 카운팅을 하면 2개씩 나와야 정상인데, 1개인 것이 바로 다른 부분이다.

SELECT COMPARE_ID, F98
FROM (
SELECT T1.COMPARE_ID, T1.F98 FROM TABLEA T1 WHERE T1.AP_ID='A08v25'
 UNION ALL SELECT T2.COMPARE_ID, T2.F98  FROM TABLEA T2 WHERE T2.AP_ID='A10v25'
 ) t
 GROUP BY COMPARE_ID, F98
 HAVING COUNT(*) = 1
 ORDER BY COMPARE_ID
 

Written with StackEdit.

반응형

[mysql] 쿼리시 스트링을 수타입으로 정렬하기


mysql에서 쿼리시 특정 필드로 소팅 조회할 때, 숫자가 스트링인 필드일 경우, 스트링 타입으로 정렬이 된다. 

이럴 경우, 1, 10, 100이 2보다 작게 된다. (스트링 대소 비교)

따라서 넘버 타입으로 캐스팅하여 정렬하는 것이 필요하다.


select  * from MyTable order by cast(Num as unsigned) ;

or

select * from MyTable order by Num+0 ;





반응형


+mysql에서 쿼리 결과를 변수로 저장하여 사용하기


변수는 앞에 @을 붙인다.
변수에 값을 할당시 set, select로 할 수 있다. 할당시에는 := 로 한다. 

SET @user:=123456;
select @group:=group from TUSER where user=@user;
select * from user where group=@group;



반응형


+ SELECT AND INSERT
한 테이블에서 선택한 레코드들을 다른 테이블에 추가하기.  (values 대신 select 절을 사용)

INSERT INTO TABLEA (f1, f2, f3)
  SELECT f1, f2, f3 FROM TABLEB

데이터베이스가 다르면 테이블명 앞에 DB명을 써준다.
 ex)  DB1.TABLEA


+ SELECT AND UPDATE
다른 테이블에서  이 테이블의 특정필드로 select한 값을 이 테이블에서 다른 테이블의 값으로 업데이트를 한 번에 하기.

UPDATE TABLEA log, TABLEB user
SET log.MOBILE_NO = user.MOBILE_NO
WHERE log.DEVICE_ID=user.DEVICE_ID;





반응형

mysql

+그룹별로 처음 나오는 하나의 줄만 뽑아낼때


ex) CAT_ID가 같은 것들끼리 묶어서 그룹별 처음으로 나온 레코드만 그룹 대표로 하나씩 추출한다.

select * from TABLE_A group by CAT_ID ;


그룹 내에서 어떤 키로 소팅하여 최신 값을 뽑는 경우, min, max 함수등을 이용하거나 미리 order by로 정렬 후 group by로 한다.

ex)

select * from (select * from TABLE_A order by NAME desc) a group by a.CAT_ID ;

select CAT_ID, min(NAME) from TABLE_A group by CAT_ID ;



+ group by 에러

only_full_group_by 에러가 발생.

=> mysql 5.7이상 부터 group by로 select 할 때 다른 값들이 있는 컬럼들을 조회하면 에러 발생.

처음 나온 것들을 자동으로 선택하여 조회하게 하려면 서버 설정을 바꿔주어야 한다.

/etc/mysql/my.cnf

[mysqld]

sql_mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION

위와 같이 설정을 추가하여 서비스 재시작

service mysql restart





반응형

+감사로그에서 초 단위로 발생한 로그 개수 조회.

mysql

LOG_DATE 형식 VARCHAR2로 yyyy-mm-dd hh:mm:ss.sss

LOG_DATE에서 처음부터 19자까지만 얻어와서 그룹별로 카운팅.

카운트로 내림차순으로 정렬.


select * from (

select substr(LOG_DATE, 1, 19) as d, count(*) as cnt from AUDIT_LOG group by substr(LOG_DATE, 1, 19) ) A

order by cnt desc ;



+ Recent posts