1. 준비물

   라즈베리파이 (OS설치 및 SSH 설정 참고 https://opensrc.tistory.com/247)

   TFT LCD

       3.5inch TFT LCD 구매처

       국내 : https://www.devicemart.co.kr/goods/view?no=1383804

 

라즈베리파이 3.5인치 TFT LCD 디스플레이 480x320 터치스크린 모니터 [CN0002]

라즈베리파이 호환 3.5 인치 LCD 터치스크린 모니터. 480 x 320의 고해상도로 모든 이미지를 선명하게 표시

www.devicemart.co.kr

       알리 : https://ko.aliexpress.com/item/1005006355715708.html

 

TFT LCD 모듈, 라즈베리 파이 2 모델 B & RPI B/3 용, 3.5 인치 - AliExpress 502

Smarter Shopping, Better Living! Aliexpress.com

ko.aliexpress.com

 

2. 드라이버 설치

3.5인치 TFT의 경우 기본 OS 설치만으로는 화면 표시가 되지 않습니다.

 

부팅이 완료 되면 ssh 로 접속해서 제조사에서 제공하는 드라이버를 다운 받아서 실행합니다.

$ git clone https://github.com/goodtft/LCD-show
$ cd LCD-show
$ sudo ./LCD35-show

 

설치가 완료 되면 자동으로 재부팅 된다.

 

3. 설치 완료

 

끝.

라즈베리파이 홈페이지에 들어가면 공식 Imager가 올라와 있습니다.

과거처럼 필요한 이미지 파일을 다운받아서 부팅 SD카드를 만들고 wifi 설정 넣어 주고 하는 것을 한번에 할 수 있고

심지어 설정을 저장해서 같은 작업을 반복할 수 있다.

 

1. 준비물

    라즈베리파이 4B

    Micro SD카드 (8G 이상)

 

2. Raspberry Pi Imager 다운로드

    https://www.raspberrypi.com/software/

 

Raspberry Pi OS – Raspberry Pi

From industries large and small, to the kitchen table tinkerer, to the classroom coder, we make computing accessible and affordable for everybody.

www.raspberrypi.com

 

 

3. 설치 환경 선택

 

 

설치하고자 하는 환경으로 선택

 

나의 경우 

장치 : Raspberry Pi 4

운영체제 : Raspberry Pi OS (64-bit)

저장소 : SD카드

 

4. OS 커스터마이징

hostname, 사용자계정 및 비밀번호, wifi 설정, 로케일 설정, SSH 사용여부 등을 미리 설정 할 수 있다.

 

 

 

나의 환경에 맞게 수정 하고 SSH 서비스를 활성화 시켰다.

 

 

5. 부팅 Disk 생성

OS 커스터마이징 설정 적용 -> '예'를 클릭하면

 

SD카드에 있는 내용이 모두 지워진다는 경고 -> 기존 내용을 포멧 후 설치 된다.

 

이미지 쓰기 후 무결성 검증까지 하기 때문에 조금 시간이 걸리는 점 참고.

 

 

참고 : 이미지 쓰기 완료 후 뜨는 경고

이미지 쓰기가 완료 되면 완료 메시지와 함께 포멧 경고창이 뜬다.

이것은 리눅스 전용으로 생성된 파티션의 파일시스템을 윈도우에서 인식하지 못하기 때문으로 취소 하면 됨

 

6. 라즈베리파이 부팅 및 SSH 접속

SSH로 접속 하기 위해서 DHCP로부터 자동 할당된 IP를 확인해야 함.

mDNS (hostname.local) 로 접속이 된다고 하는데 잘 안되는 경우가 더 많다.

 

 

 

내 컴퓨터의 네트워크 정보 확인

대부분 가정에서 공유기를 사용해서 사설 IP를 사용하므로 내 PC의 IP 대역을 먼저 확인해야 한다.

명령 프롬프트에서 ipconfig 명령 실행

 

우리집 네트워크 환경

공유기가 192.168.45.1 이고 내 PC는 wifi를 통해 192.168.45.179 IP를 할당 받았다.

공유기에 접속을 하면 192.168.45.1~192.168.45.254 사이의 사설 IP를 DHCP서버(공유기)를 통해 할당 받는 다는 사실을 알 수 있다.

 

IP 스케너

https://www.advanced-ip-scanner.com/kr/

지정된 네트워크 대역에 사용중인 IP를 확인해주는 프로그램 설치/실행

 

스켄 범위를 192.168.45.1-254 로 지정해 주고 스캔하면 잠시후 아래와 같이 네트워크에 연결된 IP 목록이 출력된다.

인터넷에 연결된 기기가 많을 수록 목록이 많이 나옴, 새로 설치한 Raspberry Pi는 192.168.45.38에 할당된 Raspberry Pi Trading Ltd 로 추정된다.

 

SSH 클라이언트로 (https://www.putty.org/) 접속

 

최초 접속하는 경우 공개키를 저장할 것인지 물어보는 창이 표시됨 (Accept 클릭 하면 다음부터 물어보지 않음)

 

로그인 창이 나오면 아까 이미지를 구울때 OS 커스터마이징 설정에서 지정한 사용자 ID와 비밀번호를 입력한다.

(라즈베리파이 기본 계정은 pi / raspberry)

 

 

7. 기본 패키지 업데이트 및 필요 프로그램 설치

$ sudo apt update
$ sudo apt upgrade

 

무언가 설치 할 것이 있으면 'Do you want to continue? [Y/n]' 이 표시됨

최초 실행의 경우 완료 되기 까지 시간이 좀 걸림

 

나의 경우 nano 보다는 vi 에디터가 익숙해서 vi를 추가 설치 함

$ sudo apt install vim

 

재부팅 명령

$ sudo reboot

 

시스템 종료 명령

$ sudo shutdown -h now

 

끝.

사전 배경

고객 정보 저장시 개인정보 컬럼(이름, 생년월일, 전화번호, 계좌번호... 등등) 암호화 저장이 필요함

암/복호화가 가능한 방식으로 최소 권고 사항을 봤을 때 AES128 이상 적용해야 함

어플리케이션에서 암호화 복호화를 수행해서 저장하여도 되지만... 어플리케이션 로그등에 평문 개인정보가 남는 문제가 생겨서 DB 펑션으로 해결 하기로 함.

적용 암호 알고리즘

AES (AES128과 AES256은 암복호화 키의 길이에 따라 16bit 면 AES128, 32bit면 AES256 으로 분리되는 것 같다)

우리는 AES256으로 할 예정이므로 32bit의 암호화 키를 미리 준비 하자.

 

1. 암호화

CREATE FUNCTION AES256_ENCRYPT(plainText VARCHAR(1000)) RETURNS varchar(1000)
    DETERMINISTIC
BEGIN
	DECLARE returnVal VARCHAR(1000);
	SELECT HEX(AES_ENCRYPT(plainText, '32bit 암호화키'))
	INTO returnVal;
	RETURN returnVal;
END

 

2. 복호화

CREATE FUNCTION AES256_DECRYPT(encryptedText VARCHAR(1000)) RETURNS varchar(1000)
    DETERMINISTIC
BEGIN
	DECLARE returnVal VARCHAR(1000);
	SELECT CAST(AES_DECRYPT(UNHEX(encryptedText), '32bit 암호화키') AS CHAR)
	INTO returnVal;
	RETURN returnVal;
END

(암호화키는 당연히 암호화 할 때 사용한 암호화 키를 넣어 줘야 함)

 

3. 사용법

3-1. 고객정보 테이블(예시) 생성

CREATE TABLE CUSTOMER_INFO (
	SEQ INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '고객 순번',
    PHONE VARCHAR(255) NOT NULL COMMENT '전화번호',
    NAME VARCHAR(255) NOT NULL COMMENT '이름',
    BIRTH_DT VARCHAR(255) NOT NULL COMMENT '생년월일',
    GENDER VARCHAR(255) NOT NULL COMMENT '성별',
    EMAIL VARCHAR(255) NOT NULL COMMENT '이메일',
    PRIMARY KEY (SEQ),
    INDEX (PHONE)
) ENGINE=InnoDB COMMENT="고객 정보";

 

3-2. 고객 정보 입력

INSERT INTO CUSTOMER_INFO (
	PHONE, NAME, BIRTH_DT, GENDER, EMAIL
) VALUES (
	AES256_ENCRYPT('01012345678'), AES256_ENCRYPT('홍길동'), AES256_ENCRYPT('19901001'), AES256_ENCRYPT('M'), AES256_ENCRYPT('asdf@google.com')	
);

 

3-3. 고객정보 조회

SELECT
	SEQ,
	AES256_DECRYPT(PHONE) AS PHONE,
	AES256_DECRYPT(NAME) AS NAME,
	AES256_DECRYPT(BIRTH_DT) AS BIRTH_DT,
	AES256_DECRYPT(GENDER) AS GENDER,
	AES256_DECRYPT(EMAIL) AS EMAIL
FROM CUSTOMER_INFO
WHERE PHONE = AES256_ENCRYPT('01012345678')

 

 

4. 참고1 ( DETERMINISTIC )

펑션 선언에 쓰인 DETERMINISTIC 구문은 생략할 경우 기본 적으로 NOT DETERMINISTIC 로 정의 된다, 해당 구문은 동일한 입력값에 대해 동일한 결과값을 반환 하는 경우에만 유효 하며 성능에 지대한 영향을 주니 참고 하자.

 

5. 참고2 (암호화키 보안 문제)

위와 같이 함수를 선언하는 경우 사용자 생성시 모든 권한을 부여 하게 되면 사용자가 마음만 먹으면 언제든지 암호회 키를 조회 할 수 있다.

이것을 회피 하는 방법으로는

함수를 생성한 definer 계정 외에 일반 사용자 계정을 분리 하고 일반 사용자는 해당 함수의 실행 권한만 부여 하는 방법으로 가능하다.

아래와 같이 계정 생성시 모든 권한이 부여된 사용자.

MySQL [mysql]> create user 'user01'@'192.168.1.101' identified by '비밀번호';
Query OK, 0 rows affected (0.01 sec)

MySQL [mysql]> grant all privileges on mydatabase.* to 'user01'@'192.168.1.101';
Query OK, 0 rows affected (0.00 sec)

MySQL [mysql]> flush privileges;
Query OK, 0 rows affected (0.00 sec)

MariaDB [mysql]> show grants for  'user01'@'192.168.1.101';
+--------------------------------------------------------------------+
| Grants for user01@192.168.1.101                                      |
+--------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `user01`@`192.168.1.101` IDENTIFIED '비밀번호' |
| GRANT ALL PRIVILEGES ON `mydatabase`.* TO `user01`@`192.168.1.101`   |
+--------------------------------------------------------------------+
2 rows in set (0.000 sec)

MariaDB [mysql]>

해당 사용자에게 펑션의 권한을 삭제 해보자

MySQL [mysql]> REVOKE EXECUTE ON FUNCTION mydatabase.AES256_DECRYPT FROM 'user01'@'192.168.1.101';
ERROR 1403 (42000): There is no such grant defined for user 'user01' on host '192.168.1.101' on routine 'AES256_DECRYPT'

MySQL [mysql]>

모든 권한을 가진 사용자에게서 특정 권한만 제거 할 수 없는 듯

 

이미 부여된 권한 제거

MySQL [mysql]> REVOKE ALL ON mydatabase.* FROM 'user01'@'192.168.1.101';
Query OK, 0 rows affected (0.00 sec)

MySQL [mysql]> flush privileges;
Query OK, 0 rows affected (0.01 sec)

MySQL [mysql]>

 

사용자의 실제 권한에 따라 차등 부여 (여기서는 조회, 입력, 수정, 삭제만 부여)

MySQL [mysql]> GRANT SELECT, INSERT, UPDATE, DELETE ON mydatabase.* TO 'user01'@'192.168.1.101';
Query OK, 0 rows affected (0.01 sec)

MySQL [mysql]> flush privileges;
Query OK, 0 rows affected (0.01 sec)

MySQL [mysql]>

위 사용자에게 보안이 필요한 펑션의 실행 권한만 부여

MySQL [mysql]> GRANT EXECUTE ON FUNCTION mydatabase.AES256_ENCRYPT TO 'user01'@'192.168.1.101';
Query OK, 0 rows affected (0.00 sec)

MySQL [mysql]> flush privileges;
Query OK, 0 rows affected (0.00 sec)

MySQL [mysql]> show grants for 'user01'@'192.168.1.101';
+-------------------------------------------------------------------------------------+
| Grants for user01@192.168.1.101                                                     |
+-------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `user01`@`192.168.1.101`                                      |
| GRANT SELECT, INSERT, UPDATE, DELETE ON mydatabase`.* TO `user01`@`192.168.1.101`   |
| GRANT EXECUTE ON FUNCTION `mydatabase`.`aes128_encrypt` TO `user01`@`192.168.1.101` |
+-------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)

MySQL [mysql]>

사용자가 많은 경우 매우 귀찮은 작업이 될 수 있다.

 

아래 글 참고 하여 그룹 기반의 권한을 부여하는 것도 좋은 방법.

https://opensrc.tistory.com/236

 

[MariaDB] 그룹 기반 권한 부여

그룹 생성, 그룹에 권한 부여MariaDB [mysql]> CREATE ROLE developer;Query OK, 0 rows affected (0.012 sec)MariaDB [mysql]> SHOW DATABASES;+--------------------+| Database |+--------------------+| webservice || information_schema || mysql || perform

opensrc.tistory.com

 

참고 3 (동일한 결과를 리턴하는 Java 코드)

( apache-common 패키지 필요)

import java.io.UnsupportedEncodingException;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.CharEncoding;
import org.apache.commons.codec.binary.Hex;
/**
 * MariaDB 암/복호화 Java 테스트
 * @author kyuyoung.lee
 *
 */
public class MariaDBAESTest {
	private static final String key = "위에서 사용한 암호화키 동일하게";
	private static SecretKeySpec genAesKey(final String key, final String encoding) {
		try {
			final byte[] finalKey = new byte[16];
			int i = 0;
			for(byte b : key.getBytes(encoding)) {
				finalKey[i++ % 16] ^= b;
			}
			return new SecretKeySpec (finalKey, "AES");
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}
	public static String encrypt(String plainText) throws Exception {
		// Encrypt
		final Cipher encryptCiper = Cipher.getInstance("AES");
		encryptCiper.init(Cipher.ENCRYPT_MODE, genAesKey(key, "UTF-8"));
		String encStr = new String(Hex.encodeHex(encryptCiper.doFinal(plainText.getBytes("UTF-8")))).toUpperCase();
		return encStr;
	}
	public static String decrypt(String encryptedText) throws Exception {
		// Decrypt
		final Cipher decryptCiper = Cipher.getInstance("AES");
		decryptCiper.init(Cipher.DECRYPT_MODE, genAesKey(key, "UTF-8"));
		String decStr = new String(decryptCiper.doFinal(Hex.decodeHex(encryptedText.toCharArray())), CharEncoding.UTF_8);
		return decStr;
	}
	public static void main (String [] args) throws Exception {
		String plainText = "123456ABCdef";
		System.out.println("Plain Text : " + plainText);
		String encryptedText = MariaDBAESTest.encrypt(plainText);
		System.out.println("Encrypted Text : " + encryptedText);
		String decryptedText = MariaDBAESTest.decrypt(encryptedText);
		System.out.println("Decrypted Text : " + decryptedText);
	}
}

Good Luck!

사전 배경

MariaDB 10.4.x 버전의 사용자 비밀번호 해쉬 방식은 기본 sha1로 보안점검에 취약 사항으로 도출 됨

sha2(256) 업그레이드 권고를 받았지만 기본적으로 지원하지 않아서 별도의 플러그인을 설치 해야 함

몇가지 방법이 있지만 ed25519(ECDSA) 알고리즘을 적용하기로 함

 

ed25519(ECDSA) 알고리즘에 대한 설명

https://ko.wikipedia.org/wiki/%ED%83%80%EC%9B%90%EA%B3%A1%EC%84%A0_DSA

 

MariaDB ed25519플러그인에 대한 설명

https://runebook.dev/ko/docs/mariadb/authentication-plugin-ed25519/index

 

주의 사항

해당 플러그인을 설치 하면 jdbc 연결시 MySQL 드라이버를 사용 던 아래 방식을 할 수 없고 MariaDB 전용 드라이버를 써야 함

기존 MySQL 드라이버를 사용 할 수 없음

Class.forName("com.mysql.jdbc.Driver");

... 생략 ...

String url = "jdbc:mysql://localhost:3306/mydatabase?...";
Connection con = DriverManager.getConnection(url, "user", "password");
... 생략 ...

수정 (Maven 기준)

        <dependency>
            <groupId>org.mariadb.jdbc</groupId>
            <artifactId>mariadb-java-client</artifactId>
            <version>${적합한 버전}</version>
        </dependency>
Class.forName("org.mariadb.jdbc.Dirver");
... 생략 ...
String url = "jdbc:mariadb://localhost:3306/mydatabase?...";
Connection con = DriverManager.getConnection(url, "user", "password");
... 생략 ...

 

1. 설치

1-1. 플러그인 디렉토리 확인 및 ed25519 플러그인 설치 여부 확인

MariaDB [mysql]> show global variables like 'plugin_dir%';
+---------------+--------------------------+
| Variable_name | Value                    |
+---------------+--------------------------+
| plugin_dir    | /usr/lib64/mysql/plugin/ |
+---------------+--------------------------+
1 row in set (0.002 sec)
MariaDB [mysql]> show plugins;
+-------------------------------+----------+---------------------+--------------------------+---------+
| Name                          | Status   | Type                | Library                  | License |
+-------------------------------+----------+---------------------+--------------------------+---------+
| binlog                        | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| mysql_native_password         | ACTIVE   | AUTHENTICATION      | NULL                     | GPL     |
| mysql_old_password            | ACTIVE   | AUTHENTICATION      | NULL                     | GPL     |
| wsrep                         | ACTIVE   | REPLICATION         | NULL                     | GPL     |
| CSV                           | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| MEMORY                        | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| Aria                          | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| MyISAM                        | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| MRG_MyISAM                    | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| CLIENT_STATISTICS             | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INDEX_STATISTICS              | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| TABLE_STATISTICS              | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| USER_STATISTICS               | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| SQL_SEQUENCE                  | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| InnoDB                        | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| INNODB_TRX                    | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_LOCKS                  | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_LOCK_WAITS             | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMP                    | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMP_RESET              | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMPMEM                 | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMPMEM_RESET           | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMP_PER_INDEX          | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMP_PER_INDEX_RESET    | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_BUFFER_PAGE            | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_BUFFER_PAGE_LRU        | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_BUFFER_POOL_STATS      | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_METRICS                | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_DEFAULT_STOPWORD    | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_DELETED             | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_BEING_DELETED       | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_CONFIG              | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_INDEX_CACHE         | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_INDEX_TABLE         | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_TABLES             | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_TABLESTATS         | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_INDEXES            | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_COLUMNS            | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_FIELDS             | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_FOREIGN            | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_FOREIGN_COLS       | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_TABLESPACES        | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_DATAFILES          | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_VIRTUAL            | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_MUTEXES                | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_SEMAPHORE_WAITS    | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_TABLESPACES_ENCRYPTION | ACTIVE   | INFORMATION SCHEMA  | NULL                     | BSD     |
| INNODB_TABLESPACES_SCRUBBING  | ACTIVE   | INFORMATION SCHEMA  | NULL                     | BSD     |
| PERFORMANCE_SCHEMA            | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| SEQUENCE                      | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| unix_socket                   | ACTIVE   | AUTHENTICATION      | NULL                     | GPL     |
| FEEDBACK                      | DISABLED | INFORMATION SCHEMA  | NULL                     | GPL     |
| user_variables                | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| partition                     | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| SERVER_AUDIT                  | ACTIVE   | AUDIT               | server_audit.so          | GPL     |
| simple_password_check         | ACTIVE   | PASSWORD VALIDATION | simple_password_check.so | GPL     |
+-------------------------------+----------+---------------------+--------------------------+---------+
56 rows in set (0.002 sec)
MariaDB [mysql]>
[root@EbMP_STG ~]# ls -al /usr/lib64/mysql/plugin/
합계 8920
drwxr-xr-x. 3 root  root    4096  4월  2  2021 .
drwxr-xr-x. 3 root  root      20  4월  2  2021 ..
-rwxr-xr-x  1 root  root   72048  2월 19  2021 auth_ed25519.so
-rwxr-xr-x  1 root  root   11136  2월 19  2021 auth_gssapi_client.so
-rwxr-xr-x  1 root  root   11672  2월 19  2021 auth_pam.so
drwx------  2 mysql root      27  4월  2  2021 auth_pam_tool_dir
-rwxr-xr-x  1 root  root   11672  2월 19  2021 auth_pam_v1.so
-rwxr-xr-x  1 root  root   11152  2월 19  2021 caching_sha2_password.so
-rwxr-xr-x  1 root  root   75688  2월 19  2021 client_ed25519.so    <-- 기본 설치 되어 있음
-rwxr-xr-x  1 root  root   11120  2월 19  2021 dialog.so
-rwxr-xr-x  1 root  root   11776  2월 19  2021 disks.so
-rwxr-xr-x  1 root  root   20208  2월 19  2021 file_key_management.so
-rwxr-xr-x  1 root  root  107344  2월 19  2021 ha_archive.so
-rwxr-xr-x  1 root  root   74504  2월 19  2021 ha_blackhole.so
-rwxr-xr-x  1 root  root  103352  2월 19  2021 ha_federated.so
-rwxr-xr-x  1 root  root  144376  2월 19  2021 ha_federatedx.so
-rwxr-xr-x  1 root  root 6585928  2월 19  2021 ha_mroonga.so
-rwxr-xr-x  1 root  root  197648  2월 19  2021 ha_sphinx.so
-rwxr-xr-x  1 root  root 1190840  2월 19  2021 ha_spider.so
-rwxr-xr-x  1 root  root  243816  2월 19  2021 handlersocket.so
-rwxr-xr-x  1 root  root   11888  2월 19  2021 locales.so
-rwxr-xr-x  1 root  root   11792  2월 19  2021 metadata_lock_info.so
-rwxr-xr-x  1 root  root    6992  2월 19  2021 mysql_clear_password.so
-rwxr-xr-x  1 root  root   12536  2월 19  2021 query_cache_info.so
-rwxr-xr-x  1 root  root   16240  2월 19  2021 query_response_time.so
-rwxr-xr-x  1 root  root   61544  2월 19  2021 server_audit.so
-rwxr-xr-x  1 root  root   11096  2월 19  2021 sha256_password.so
-rwxr-xr-x  1 root  root   11800  2월 19  2021 simple_password_check.so
-rwxr-xr-x  1 root  root   11936  2월 19  2021 sql_errlog.so
-rwxr-xr-x  1 root  root   46184  2월 19  2021 wsrep_info.so
[root@EbMP_STG ~]#

플러그인 디렉토리에 해당 플러그인이 존재 하지만 활성화 되어 있지는 않음

 

2. 플러그인 설치

MariaDB [mysql]> install soname 'auth_ed25519';
Query OK, 0 rows affected (0.431 sec)
MariaDB [mysql]> show plugins;
+-------------------------------+----------+---------------------+--------------------------+---------+
| Name                          | Status   | Type                | Library                  | License |
+-------------------------------+----------+---------------------+--------------------------+---------+
| binlog                        | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| mysql_native_password         | ACTIVE   | AUTHENTICATION      | NULL                     | GPL     |
| mysql_old_password            | ACTIVE   | AUTHENTICATION      | NULL                     | GPL     |
| wsrep                         | ACTIVE   | REPLICATION         | NULL                     | GPL     |
| CSV                           | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| MEMORY                        | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| Aria                          | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| MyISAM                        | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| MRG_MyISAM                    | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| CLIENT_STATISTICS             | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INDEX_STATISTICS              | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| TABLE_STATISTICS              | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| USER_STATISTICS               | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| SQL_SEQUENCE                  | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| InnoDB                        | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| INNODB_TRX                    | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_LOCKS                  | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_LOCK_WAITS             | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMP                    | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMP_RESET              | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMPMEM                 | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMPMEM_RESET           | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMP_PER_INDEX          | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMP_PER_INDEX_RESET    | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_BUFFER_PAGE            | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_BUFFER_PAGE_LRU        | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_BUFFER_POOL_STATS      | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_METRICS                | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_DEFAULT_STOPWORD    | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_DELETED             | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_BEING_DELETED       | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_CONFIG              | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_INDEX_CACHE         | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_INDEX_TABLE         | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_TABLES             | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_TABLESTATS         | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_INDEXES            | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_COLUMNS            | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_FIELDS             | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_FOREIGN            | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_FOREIGN_COLS       | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_TABLESPACES        | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_DATAFILES          | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_VIRTUAL            | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_MUTEXES                | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_SEMAPHORE_WAITS    | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_TABLESPACES_ENCRYPTION | ACTIVE   | INFORMATION SCHEMA  | NULL                     | BSD     |
| INNODB_TABLESPACES_SCRUBBING  | ACTIVE   | INFORMATION SCHEMA  | NULL                     | BSD     |
| PERFORMANCE_SCHEMA            | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| SEQUENCE                      | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| unix_socket                   | ACTIVE   | AUTHENTICATION      | NULL                     | GPL     |
| FEEDBACK                      | DISABLED | INFORMATION SCHEMA  | NULL                     | GPL     |
| user_variables                | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| partition                     | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| SERVER_AUDIT                  | ACTIVE   | AUDIT               | server_audit.so          | GPL     |
| simple_password_check         | ACTIVE   | PASSWORD VALIDATION | simple_password_check.so | GPL     |
| ed25519                       | ACTIVE   | AUTHENTICATION      | auth_ed25519.so          | GPL     |
+-------------------------------+----------+---------------------+--------------------------+---------+
57 rows in set (0.002 sec)
MariaDB [mysql]>

콘솔에서 설치한 것 만으로 DB재시작 시에도 적용이 됨. (나의 경우 my.cnf에 플러그인을 로드 하도록 설정 하면 재시작시 오류 발생함)

 

3. 사용자계정 적용

사용자 계정 생성시 해당 알고리즘을 사용 하도록 수정해야 함

CREATE USER '사용자ID'@'사용IP' IDENTIFIED VIA ed25519 USING  PASSWORD ('{비밀번호}') PASSWORD EXPIRE INTERVAL 90 DAY;

비밀번호 만료 기한 90일 적용

Good Luck!

 

MariaDB [mysql]> show global variables like 'simple_password%';
+-----------------------------------------+-------+
| Variable_name                           | Value |
+-----------------------------------------+-------+
| simple_password_check_digits            | 1     |
| simple_password_check_letters_same_case | 1     |
| simple_password_check_minimal_length    | 8     |
| simple_password_check_other_characters  | 1     |
+-----------------------------------------+-------+
4 rows in set (0.002 sec)
MariaDB [mysql]>

사전 배경

일년에 몇번씩 받는 보안점검... 항상 문제가 되는 것이 DB 계정의 비밀번호 복잡도를 강제하고 있는지 여부

가장 낮은 수준의 요건이 비밀번호 최소자리수 8자 이상 영문 대문자 1, 소문자 1, 특수문자 1 이상, 비밀번호 변경 주기 90일 이내 정도는 항상 등장하고

추가로 최근 n회 비밀번호 사용 금지, 사용자 계정명, 전화번호 등 유추하기 쉬운 비밀번호 금지

(참고로 우리가 사용하는 MariaDB 10.4.* 에서는 최근 n회 비밀번호 금지, 사용자 계정명이 포함된 비밀번호 금지 등이 적용 할 수 있는 방법이 없다. 아마도 MariaDB 10.5 이상에서 지원 하는 듯?)

기본 적인 복잡도라도 적용이 필요 한 상황, 이미 비밀번호에 대한 제약조건이 적용되어 있거나, 플러그인이 설치 되어 있으면 다행이지만

DB 설치 후 아무 작업도 하지 않으면 계정 비밀번호에 대한 제약이 없다.(MariaDB 10.4.x 기준)

 

적용

simple_password_check 플러그인을 통해 MariaDB Password 복잡도를 강제 하는 방법

MySQL 5.7 은 기본 포함, 없으면 상위 버전에서 simple_password_check.so 파일을 복사해서 설정 가능함

(참고 : MariaDB 10.x 는 MySQL 5.7에 해당, 이후 버전은 상호 DB간 별도로 소스를 운영하면서 더이상 호환이 되지 않는 부분이 많음)

1. 플러그인 설치 여부 확인

1-1. 플러그인 디렉토리 위치 확인

MariaDB [mysql]> show global variables like 'plugin_dir%';
+---------------+--------------------------+
| Variable_name | Value                    |
+---------------+--------------------------+
| plugin_dir    | /usr/lib64/mysql/plugin/ |
+---------------+--------------------------+
1 row in set (0.002 sec)
MariaDB [mysql]>

1-2. simple_password_check.so 유무 확인

[root@mydbserver user01]# ls -al /usr/lib64/mysql/plugin/
합계 8920
drwxr-xr-x. 3 root  root    4096  4월  2  2021 .
drwxr-xr-x. 3 root  root      20  4월  2  2021 ..
-rwxr-xr-x  1 root  root   72048  2월 19  2021 auth_ed25519.so
-rwxr-xr-x  1 root  root   11136  2월 19  2021 auth_gssapi_client.so
-rwxr-xr-x  1 root  root   11672  2월 19  2021 auth_pam.so
drwx------  2 mysql root      27  4월  2  2021 auth_pam_tool_dir
-rwxr-xr-x  1 root  root   11672  2월 19  2021 auth_pam_v1.so
-rwxr-xr-x  1 root  root   11152  2월 19  2021 caching_sha2_password.so
-rwxr-xr-x  1 root  root   75688  2월 19  2021 client_ed25519.so
-rwxr-xr-x  1 root  root   11120  2월 19  2021 dialog.so
-rwxr-xr-x  1 root  root   11776  2월 19  2021 disks.so
-rwxr-xr-x  1 root  root   20208  2월 19  2021 file_key_management.so
-rwxr-xr-x  1 root  root  107344  2월 19  2021 ha_archive.so
-rwxr-xr-x  1 root  root   74504  2월 19  2021 ha_blackhole.so
-rwxr-xr-x  1 root  root  103352  2월 19  2021 ha_federated.so
-rwxr-xr-x  1 root  root  144376  2월 19  2021 ha_federatedx.so
-rwxr-xr-x  1 root  root 6585928  2월 19  2021 ha_mroonga.so
-rwxr-xr-x  1 root  root  197648  2월 19  2021 ha_sphinx.so
-rwxr-xr-x  1 root  root 1190840  2월 19  2021 ha_spider.so
-rwxr-xr-x  1 root  root  243816  2월 19  2021 handlersocket.so
-rwxr-xr-x  1 root  root   11888  2월 19  2021 locales.so
-rwxr-xr-x  1 root  root   11792  2월 19  2021 metadata_lock_info.so
-rwxr-xr-x  1 root  root    6992  2월 19  2021 mysql_clear_password.so
-rwxr-xr-x  1 root  root   12536  2월 19  2021 query_cache_info.so
-rwxr-xr-x  1 root  root   16240  2월 19  2021 query_response_time.so
-rwxr-xr-x  1 root  root   61544  2월 19  2021 server_audit.so
-rwxr-xr-x  1 root  root   11096  2월 19  2021 sha256_password.so
-rwxr-xr-x  1 root  root   11800  2월 19  2021 simple_password_check.so <--- 이놈
-rwxr-xr-x  1 root  root   11936  2월 19  2021 sql_errlog.so
-rwxr-xr-x  1 root  root   46184  2월 19  2021 wsrep_info.so
[root@mydbserver user01]#

플러그인 파일은 존재 함 ( MariaDB 10.4.x 기준 기본 패키지로 설치 되어 있고 활성화만 안되어 있을 것임)

 

1-3. simple_password_check 플러그인이 활성화 되어 있는지 확인

MariaDB [mysql]> show global variables like 'simple_password%';
Empty set (0.002 sec)

MariaDB [mysql]>
MariaDB [mysql]> show plugins;
+-------------------------------+----------+--------------------+---------+---------+
| Name                          | Status   | Type               | Library | License |
+-------------------------------+----------+--------------------+---------+---------+
| binlog                        | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| mysql_native_password         | ACTIVE   | AUTHENTICATION     | NULL    | GPL     |
| mysql_old_password            | ACTIVE   | AUTHENTICATION     | NULL    | GPL     |
| wsrep                         | ACTIVE   | REPLICATION        | NULL    | GPL     |
| CSV                           | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| MEMORY                        | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| Aria                          | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| MyISAM                        | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| MRG_MyISAM                    | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| CLIENT_STATISTICS             | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INDEX_STATISTICS              | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| TABLE_STATISTICS              | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| USER_STATISTICS               | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| SQL_SEQUENCE                  | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| InnoDB                        | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| INNODB_TRX                    | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_LOCKS                  | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_LOCK_WAITS             | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_CMP                    | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_CMP_RESET              | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_CMPMEM                 | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_CMPMEM_RESET           | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_CMP_PER_INDEX          | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_CMP_PER_INDEX_RESET    | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_BUFFER_PAGE            | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_BUFFER_PAGE_LRU        | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_BUFFER_POOL_STATS      | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_METRICS                | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_FT_DEFAULT_STOPWORD    | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_FT_DELETED             | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_FT_BEING_DELETED       | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_FT_CONFIG              | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_FT_INDEX_CACHE         | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_FT_INDEX_TABLE         | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_SYS_TABLES             | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_SYS_TABLESTATS         | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_SYS_INDEXES            | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_SYS_COLUMNS            | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_SYS_FIELDS             | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_SYS_FOREIGN            | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_SYS_FOREIGN_COLS       | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_SYS_TABLESPACES        | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_SYS_DATAFILES          | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_SYS_VIRTUAL            | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_MUTEXES                | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_SYS_SEMAPHORE_WAITS    | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| INNODB_TABLESPACES_ENCRYPTION | ACTIVE   | INFORMATION SCHEMA | NULL    | BSD     |
| INNODB_TABLESPACES_SCRUBBING  | ACTIVE   | INFORMATION SCHEMA | NULL    | BSD     |
| PERFORMANCE_SCHEMA            | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| SEQUENCE                      | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| unix_socket                   | ACTIVE   | AUTHENTICATION     | NULL    | GPL     |
| FEEDBACK                      | DISABLED | INFORMATION SCHEMA | NULL    | GPL     |
| user_variables                | ACTIVE   | INFORMATION SCHEMA | NULL    | GPL     |
| partition                     | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
+-------------------------------+----------+--------------------+---------+---------+
54 rows in set (0.002 sec)

MariaDB [mysql]>

안되어 있음.

 

2. 플러그인 설치

MariaDB [mysql]> install  plugin simple_password_check soname 'simple_password_check.so';
Query OK, 0 rows affected (0.039 sec)
MariaDB [mysql]> show plugins;
+-------------------------------+----------+---------------------+--------------------------+---------+
| Name                          | Status   | Type                | Library                  | License |
+-------------------------------+----------+---------------------+--------------------------+---------+
| binlog                        | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| mysql_native_password         | ACTIVE   | AUTHENTICATION      | NULL                     | GPL     |
| mysql_old_password            | ACTIVE   | AUTHENTICATION      | NULL                     | GPL     |
| wsrep                         | ACTIVE   | REPLICATION         | NULL                     | GPL     |
| CSV                           | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| MEMORY                        | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| Aria                          | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| MyISAM                        | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| MRG_MyISAM                    | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| CLIENT_STATISTICS             | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INDEX_STATISTICS              | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| TABLE_STATISTICS              | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| USER_STATISTICS               | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| SQL_SEQUENCE                  | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| InnoDB                        | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| INNODB_TRX                    | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_LOCKS                  | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_LOCK_WAITS             | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMP                    | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMP_RESET              | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMPMEM                 | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMPMEM_RESET           | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMP_PER_INDEX          | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_CMP_PER_INDEX_RESET    | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_BUFFER_PAGE            | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_BUFFER_PAGE_LRU        | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_BUFFER_POOL_STATS      | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_METRICS                | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_DEFAULT_STOPWORD    | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_DELETED             | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_BEING_DELETED       | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_CONFIG              | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_INDEX_CACHE         | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_FT_INDEX_TABLE         | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_TABLES             | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_TABLESTATS         | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_INDEXES            | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_COLUMNS            | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_FIELDS             | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_FOREIGN            | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_FOREIGN_COLS       | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_TABLESPACES        | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_DATAFILES          | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_VIRTUAL            | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_MUTEXES                | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_SYS_SEMAPHORE_WAITS    | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| INNODB_TABLESPACES_ENCRYPTION | ACTIVE   | INFORMATION SCHEMA  | NULL                     | BSD     |
| INNODB_TABLESPACES_SCRUBBING  | ACTIVE   | INFORMATION SCHEMA  | NULL                     | BSD     |
| PERFORMANCE_SCHEMA            | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| SEQUENCE                      | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| unix_socket                   | ACTIVE   | AUTHENTICATION      | NULL                     | GPL     |
| FEEDBACK                      | DISABLED | INFORMATION SCHEMA  | NULL                     | GPL     |
| user_variables                | ACTIVE   | INFORMATION SCHEMA  | NULL                     | GPL     |
| partition                     | ACTIVE   | STORAGE ENGINE      | NULL                     | GPL     |
| simple_password_check         | ACTIVE   | PASSWORD VALIDATION | simple_password_check.so | GPL     |
+-------------------------------+----------+---------------------+--------------------------+---------+
55 rows in set (0.002 sec)
MariaDB [mysql]>

플러그인 설치 완료

 

3. 복잡도 설정

3-1. 기본 설정 확인

MariaDB [mysql]> show global variables like 'simple_password%';
+-----------------------------------------+-------+
| Variable_name                           | Value |
+-----------------------------------------+-------+
| simple_password_check_digits            | 1     |
| simple_password_check_letters_same_case | 1     |
| simple_password_check_minimal_length    | 8     |
| simple_password_check_other_characters  | 1     |
+-----------------------------------------+-------+
4 rows in set (0.002 sec)
MariaDB [mysql]>

비밀번호 최소 8자, 숫자 1, 서로다른 영문 대소문자 1개 이상, 특수문자, 숫자 1자 이상으로 설정이 되어 있음

(다른 경우 값을 변경 하고, 재시작시 적용을 위해 my.cnf 도 수정이 필요함)

 

4. 비밀번호 유효기간 설정

참고 : https://mariadb.com/kb/en/user-password-expiry/

사용자를 생성 할 때 지정

CREATE USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;

생성된 사용자에게 지정

ALTER USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;

사용자별 비밀번호 유효기간 확인

MariaDB [mysql]> show create user 'monty'@'localhost';
+--------------------------------------------------------------------+
| CREATE USER for monty@localhost                                    |
+--------------------------------------------------------------------+
| CREATE USER `monty`@`localhost` IDENTIFIED BY PASSWORD '*암호삭제' |
+--------------------------------------------------------------------+
1 row in set (0.000 sec)

MariaDB [mysql]>

 

전체 사용자 암호 유효기간 확인

WITH password_expiration_info AS (
  SELECT User, Host,
  IF(
   IFNULL(JSON_EXTRACT(Priv, '$.password_lifetime'), -1) = -1,
   @@global.default_password_lifetime,
   JSON_EXTRACT(Priv, '$.password_lifetime')
  ) AS password_lifetime,
  JSON_EXTRACT(Priv, '$.password_last_changed') AS password_last_changed
  FROM mysql.global_priv
)
SELECT pei.User, pei.Host,
  pei.password_lifetime,
  FROM_UNIXTIME(pei.password_last_changed) AS password_last_changed_datetime,
  FROM_UNIXTIME(
   pei.password_last_changed +
   (pei.password_lifetime * 60 * 60 * 24)
  ) AS password_expiration_datetime
  FROM password_expiration_info pei
  WHERE pei.password_lifetime != 0
   AND pei.password_last_changed IS NOT NULL
UNION
SELECT pei.User, pei.Host,
  pei.password_lifetime,
  FROM_UNIXTIME(pei.password_last_changed) AS password_last_changed_datetime,
  0 AS password_expiration_datetime
  FROM password_expiration_info pei
  WHERE pei.password_lifetime = 0
   OR pei.password_last_changed IS NULL;

만일을 위해 시스템, 서비스운영 계정은 제외 하고 개별 사용자 계정에만 비밀번호 만료일자를 지정 하였다.

 

비밀번호 만료시 

'SQL  Error [1820] [HY000]: (conn=xxxxxxxx) You must SET PASSWORD before executing this statement'

오류 발생함

MySQL/MariaDB root 계정으로 접속해서

SET PASSWORD FOR 'User'@'Host' = PASSWORD('Password');

 

 

Good Luck!

라즈베리파이 설치 할 때 키보드 마우스 연결하기 매우 귀찮았었는데, 알리에서 좋은 솔루션을 찾았습니다.

https://ko.aliexpress.com/item/1005005489285231.html

 

Rii K06 미니 블루투스 무선 백라이트 키보드, 2.4GHz, IR 학습 터치패드 포함, 안드로이드 TV 박스, 맥

Smarter Shopping, Better Living! Aliexpress.com

ko.aliexpress.com

 

가격은 사악하지만, 손바닥 만한 놈이 USB 2.4GHz , 블루투스 연결이 되고 리모콘기능까지 있다고 해서 구입했습니다.

물건을 받고 라즈베리파이에 리시버 연결 해보니 여윽시나 잘 연결이 안됩니다.

다행이 7인치 터치 디스플레이가 있어서 블루투스로 잡으니 잘 동작 합니다.

하지만 라즈베리파이 설치 후 부팅하면 바로 USB로 잡혔으면 좋겠는데... 잘 안됩니다.

 

혹시나 드라이버 문제일까 싶어서 Windows 10 노트북에 USB 리시버를 꼽아 보니 'Wireless Receiver'가 준비 됐다고 나오고 장치에도 표시가 되지만 키보드의 파란색 불이 깜빡거리면서 연결이 되지 않습니다.

구매한지 몇달이 지났지만... 상품페이지 후기란에 보니 다른 사람들은 USB로도 잘 사용하고 있다고...

판매자에게 문의 했습니다.

답변

Hello, please follow the steps below to connect.
1. Open the keyboard
2. Press and hold the "FN+Caps" key, and you will observe that the LDE light on the keyboard turns green
3. Press and hold "FN+Shift". When the green light flashes rapidly, you insert the receiver and the light stops flashing, indicating a successful connection.
If you still cannot connect after following the steps below, please leave me a message and I will give you a free receiver as a gift.

1. 리시버를 PC에서 분리한 상태로 키보드 전원 On

2. "FN+Caps"키를 길게 누르면 키보드 왼쪽 상단의 녹색 LED가 깜빡 거립니다.

3. 다시 "FN+Shift"키를 길게 누르면, 녹색 LED가 빠르게 깜빡입니다. 이때 USB 수신기를 노트북에 삽입하면 연결이 되면서 깜빡임을 멈추고 녹색 LED가 켜진 상태로 됩니다.

정상 작동 와우~

 

위 작업은 아마도 USB리시버와 키보드간의 페어링이 끊어진 경우 하면 되는 것 같고

USB리시버를 다시 꼽았다 켜도 바로 연결 됩니다.

 

추가1 : 라즈베리파이 최초 설치 후 특수키 (@, #)  안되는 것

설치시 키보드 레이아웃을 us로 한 경우 shift + 2 => ?, shift + 3 =? 이상한 문자가 찍힘

해결책 : 키보드 레이아웃을 korean 으로 변경 해야 함

 

추가2 : 언어 전환

1. Windows 10 Pro : alt + space (한/영 전환 잘 됨)

2. 라즈베리파이 : shift + space (한글 폰트가 필요 한듯)

 

추가2 : 라즈베리파이 해상도 변경 관련 참고글

https://ds5qdr-dv.tistory.com/178

 

2021-01-23 RPi : 라즈베리파이용 LCD 해상도 변경

다양한 제품의 LCD를 라드베리파이에 적용중에 있을 것입니다 해상도 맞추는 방법에 대해 정리하여 올립니다 putty로 라즈베리파이에 접속하여 config.txt 파일을 열고 sudo nano /boot/config.txt 파일 제

ds5qdr-dv.tistory.com

https://blog.naver.com/roboholic84/221065527428

 

 

끝.

'자료실' 카테고리의 다른 글

리얼포스 R2SA 설정 키  (0) 2024.08.23
Windows tail 어플리케이션  (0) 2008.10.28
Unix 스타일의 Windows용 tail grap  (0) 2008.10.28

리얼포스 r2는 딥스위치가 없습니다. 대신 Fn 조합으로 기능키들을 설정할 수 있어요~~


Fn + F1 : 브라우저 열기
Fn + F2 : 메일 프로그램 시작
Fn + F3 : 계산기 시작
Fn + F4 : 미디어 플레이어 시작
Fn + F5 : 이전 미디어로 돌아가기 ※1
Fn + F6 :  재생 / 일시정지 ※1
Fn + F7 :  다음 미디어로 진행 ※1
Fn + F8 :  미디어 중지 ※1
Fn + F9 : 설정을 저장 ※2
Fn + F10 : -
Fn + F11 : 좌측 Ctrl, Caps Lock 키 기능 교체
Fn + F12 :  키 잠금 설정 / 해제 ※3 (사전 소프트웨어에서 키 할당 필요)

Fn + F11 하시고 Fn + F9로 저장하시면 됩니다.

DB 계정 별로 모든 권한을 부여하지 않고 차등 권한을 부여하기 위해

계정별로 그룹(role)을 생성, 그룹에 권한 부여 하는 방법 테스트

MariaDB [mysql]> CREATE ROLE developer;
Query OK, 0 rows affected (0.012 sec)

MariaDB [mysql]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| webservice         |
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.001 sec)

MariaDB [mysql]> GRANT SELECT,INSERT,UPDATE,DELETE ON webservice.* TO developer;
Query OK, 0 rows affected (0.032 sec)

MariaDB [mysql]> SHOW GRANTS FOR developer;
+-----------------------------------------------------------------------+
| Grants for developer                                                  |
+-----------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `developer`                                     |
| GRANT SELECT, INSERT, UPDATE, DELETE ON `webservice`.* TO `developer` |
+-----------------------------------------------------------------------+
2 rows in set (0.001 sec)

MariaDB [mysql]>
MariaDB [mysql]> flush privileges;
Query OK, 0 rows affected (0.002 sec)

MariaDB [mysql]>

 

기존 사용자에게 그룹 롤 부여

MariaDB [mysql]> show grants for 'ky.lee'@'172.30.2.27';
+---------------------------------------------------------------------------------+
| Grants for ky.lee@172.30.2.27                                                   |
+---------------------------------------------------------------------------------+
| GRANT `developer` TO `ky.lee`@`172.30.2.27`                                     |
| GRANT USAGE ON *.* TO `ky.lee`@`172.30.2.27` IDENTIFIED BY PASSWORD '*보안삭제' |
| GRANT SELECT, INSERT, UPDATE, DELETE ON `fb_ebmp`.* TO `ky.lee`@`172.30.2.27`   |
+---------------------------------------------------------------------------------+
3 rows in set (0.000 sec)

MariaDB [mysql]> revoke ALL ON webservice.* from 'ky.lee'@'172.30.2.27';
Query OK, 0 rows affected (0.017 sec)

MariaDB [mysql]> flush privileges;
Query OK, 0 rows affected (0.001 sec)

MariaDB [mysql]> select current_role;
+--------------+
| current_role |
+--------------+
| NULL         |
+--------------+
1 row in set (0.000 sec)

MariaDB [mysql]> set role developer;
Query OK, 0 rows affected (0.000 sec)

MariaDB [mysql]> select current_role;
+--------------+
| current_role |
+--------------+
| developer    |
+--------------+
1 row in set (0.000 sec)

MariaDB [mysql]> grant developer to 'ky.lee'@'172.30.2.27';
Query OK, 0 rows affected (0.001 sec)

MariaDB [mysql]> SET DEFAULT ROLE 'developer' for 'ky.lee'@'172.30.2.27';
Query OK, 0 rows affected (0.019 sec)

MariaDB [mysql]> flush privileges;
Query OK, 0 rows affected (0.002 sec)

MariaDB [mysql]> show grants for 'ky.lee'@'172.30.2.27';
+---------------------------------------------------------------------------------+
| Grants for ky.lee@172.30.2.27                                                   |
+---------------------------------------------------------------------------------+
| GRANT `developer` TO `ky.lee`@`172.30.2.27`                                     |
| GRANT USAGE ON *.* TO `ky.lee`@`172.30.2.27` IDENTIFIED BY PASSWORD '*보안삭제' |
+---------------------------------------------------------------------------------+
2 rows in set (0.000 sec)

MariaDB [mysql]> REVOKE developer from 'ky.lee'@'172.30.2.27';
Query OK, 0 rows affected (0.029 sec)

MariaDB [mysql]> show grants for 'ky.lee'@'172.30.2.27';
+---------------------------------------------------------------------------------+
| Grants for ky.lee@172.30.2.27                                                   |
+---------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `ky.lee`@`172.30.2.27` IDENTIFIED BY PASSWORD '*보안삭제' |
+---------------------------------------------------------------------------------+
1 row in set (0.000 sec)

MariaDB [mysql]>

 

함수 권한

MariaDB [mysql]> show grants for developer;
+-------------------------------------------------------------------------------------------+
| Grants for developer                                                                      |
+-------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `developer`                                                         |
| GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE, SHOW VIEW ON `webservice`.* TO `developer` |
+-------------------------------------------------------------------------------------------+
2 rows in set (0.000 sec)

MariaDB [mysql]> revoke execute on webservice.* from developer;
Query OK, 0 rows affected (0.018 sec)

MariaDB [mysql]> show grants for developer;
+----------------------------------------------------------------------------------+
| Grants for developer                                                             |
+----------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `developer`                                                |
| GRANT SELECT, INSERT, UPDATE, DELETE, SHOW VIEW ON `webservice`.* TO `developer` |
+----------------------------------------------------------------------------------+
2 rows in set (0.000 sec)

MariaDB [mysql]> show function status where db = 'webservice';
+------------+----------------------+----------+---------------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| Db         | Name                 | Type     | Definer             | Modified            | Created             | Security_type | Comment | character_set_client | collation_connection | Database Collation |
+------------+----------------------+----------+---------------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| webservice | AES128_DECRYPT       | FUNCTION | db_admin@10.10.50.% | 2021-04-23 10:55:16 | 2021-06-07 23:35:20 | DEFINER       |         | utf8                 | utf8_general_ci      | utf8_general_ci    |
| webservice | AES128_ENCRYPT       | FUNCTION | db_admin@10.10.50.% | 2021-04-23 10:55:08 | 2021-06-07 23:35:20 | DEFINER       |         | utf8                 | utf8_general_ci      | utf8_general_ci    |
| webservice | GET_CD_NM            | FUNCTION | db_admin@10.10.50.% | 2021-11-04 18:04:36 | 2021-11-04 18:04:36 | DEFINER       |         | utf8                 | utf8_general_ci      | utf8_general_ci    |
| webservice | GET_CHILD_CD         | FUNCTION | db_admin@%          | 2022-07-04 17:02:39 | 2022-07-04 17:02:39 | DEFINER       |         | utf8mb4              | utf8mb4_general_ci   | utf8_unicode_ci    |
| webservice | GET_PARENT_CD        | FUNCTION | db_admin@10.10.50.% | 2021-11-04 18:05:07 | 2021-11-04 18:05:07 | DEFINER       |         | utf8                 | utf8_general_ci      | utf8_general_ci    |
| webservice | GET_PARENT_CD_CONCAT | FUNCTION | db_admin@10.10.50.% | 2021-11-04 18:05:28 | 2021-11-04 18:05:28 | DEFINER       |         | utf8                 | utf8_general_ci      | utf8_general_ci    |
| webservice | GET_PARENT_CD_NM     | FUNCTION | db_admin@10.10.50.% | 2021-11-04 18:05:49 | 2021-11-04 18:05:49 | DEFINER       |         | utf8                 | utf8_general_ci      | utf8_general_ci    |
+------------+----------------------+----------+---------------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
7 rows in set (0.003 sec)

MariaDB [mysql]> 
MariaDB [mysql]> show grants for developer;
+-------------------------------------------------------------------------------------------+
| Grants for developer                                                                      |
+-------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `developer`                                                         |
| GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE, SHOW VIEW ON `webservice`.* TO `developer` |
+-------------------------------------------------------------------------------------------+
2 rows in set (0.001 sec)

MariaDB [mysql]> revoke execute on webservice.* from developer;
Query OK, 0 rows affected (0.422 sec)

MariaDB [mysql]> grant execute on function webservice.AES128_ENCRYPT to developer;
Query OK, 0 rows affected (0.042 sec)

MariaDB [mysql]> flush privileges;
Query OK, 0 rows affected (0.002 sec)

MariaDB [mysql]> show grants for developer;
+----------------------------------------------------------------------------------+
| Grants for developer                                                             |
+----------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `developer`                                                |
| GRANT SELECT, INSERT, UPDATE, DELETE, SHOW VIEW ON `webservice`.* TO `developer` |
| GRANT EXECUTE ON FUNCTION `webservice`.`aes128_encrypt` TO `developer`           |
+----------------------------------------------------------------------------------+
3 rows in set (0.000 sec)

MariaDB [mysql]>

 

이상 과거 작업 내용 갈무리 한것

 

끝.

 

 

2024-10-25 추가

실제로 서버에 적용해 보면 role 을 부여받은 계정의 권한을 확인해 보면 정상으로 표시되는데, 실제 접속을 해보면

[MySQL] Access denied for user '유저아이디'@'ip'

에러가 발생함

 

몇가지 방법을 시도해 보았으나 결국 role 에 권한을 부여하고 계정에 다시 부여하는 경우는 잘 적용되지 않았습니다.

결국 계정별로 일일히 권한을 부여하는 방식으로 해결 했으나... 권한 테이블이 많이 복잡하고 유저가 많은 경우 매우 불편 할 것으로 예상되어 조금더 찾아보고 업데이트 하겠습니다.

앱의 푸시를 발송하기 위한 대기 테이블을 만들었습니다.

한명의 고객에게 동일한 푸시 1일 1회로 스트레스를 주지 않도록 하고 

푸시 생성시 발송해야 하는 시간을 정하고 싶습니다.

프로그램에서 제약을 걸어도 되지만 DB에서 물리적으로 제약을 걸어주는게 좋습니다.

결국 발송 일자를 yyyyMMdd 형태로 컬럼을 추가 하고  푸시종류 + 발송일자 + 고객 순번으로 Unique Index를 생성하면 되지만 왠지 SCHEDULE_DT와 중복되는 느낌입니다.

가상 컬럼을 이용한 인덱스를 사용해 보겠습니다.

 

1. 테이블 생성

DROP TABLE IF EXISTS OCCASIONAL_PUSH_STACK;

CREATE TABLE OCCASIONAL_PUSH_STACK (
	STACK_SEQ INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '대기 순번',
	PUSH_TYPE VARCHAR(20) NOT NULL COMMENT '푸시 종류',
	CUST_SEQ INT(11) UNSIGNED NOT NULL COMMENT '고객 순번',
	SCHEDULE_DT VARCHAR(14) NOT NULL COMMENT '발송 희망 일시',
	REG_DATE DATETIME NOT NULL COMMENT '등록 일시',
	PRIMARY KEY (STACK_SEQ)
) ENGINE=InnoDB DEFAULT CHARSET=UTF8 COMMENT='비정기 푸시 발송 대기 테이블';

 

2. 인덱스 추가

ALTER TABLE OCCASIONAL_PUSH_STACK
	ADD STD_DATE VARCHAR(8) AS (LEFT(SCHEDULE_DT, 8)) VIRTUAL AFTER CUST_SEQ,
	ADD UNIQUE INDEX (PUSH_TYPE, STD_DATE, CUST_SEQ);

CUST_SEQ 컬럼 다음에 SCHEDULE_DT 테이블의 8자리를 잘라서 가상 컬럼을 만들고, 해당 컬럼을 포함한 유니크 인덱스를 생성한다는 의미 입니다.

VIRTUAL 은 매번 사용 될 때 마다 문자열 연산을 하게 되므로 STORED 로 사용하는게 성능에는 더 유리할 것 같습니다.

3. 테이블 확인

CREATE TABLE `occasional_push_stack` (
  `STACK_SEQ` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '대기 순번',
  `PUSH_TYPE` varchar(20) NOT NULL COMMENT '푸시 종류',
  `CUST_SEQ` int(11) unsigned NOT NULL COMMENT '고객 순번',
  `STD_DATE` varchar(8) GENERATED ALWAYS AS (left(`SCHEDULE_DT`,8)) VIRTUAL,
  `SCHEDULE_DT` varchar(14) NOT NULL COMMENT '발송 희망 일시',
  `REG_DATE` datetime NOT NULL COMMENT '등록 일시',
  PRIMARY KEY (`STACK_SEQ`),
  UNIQUE KEY `PUSH_TYPE` (`PUSH_TYPE`,`STD_DATE`,`CUST_SEQ`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='비정기 푸시 발송 대기 테이블';

생성된 테이블의 DDL을 살펴 보면 위와 같이 생성되었습니다.

4. 테이터 입력

INSERT INTO OCCASIONAL_PUSH_STACK (PUSH_TYPE, CUST_SEQ, SCHEDULE_DT, REG_DATE) VALUES ('PUSH001P', 1, DATE_FORMAT(DATE_ADD(CURRENT_TIMESTAMP, INTERVAL 5 MINUTE), '%Y%m%d%H%i%s'), CURRENT_TIMESTAMP);
INSERT INTO OCCASIONAL_PUSH_STACK (PUSH_TYPE, CUST_SEQ, SCHEDULE_DT, REG_DATE) VALUES ('PUSH001P', 2, DATE_FORMAT(DATE_ADD(CURRENT_TIMESTAMP, INTERVAL 5 MINUTE), '%Y%m%d%H%i%s'), CURRENT_TIMESTAMP);
INSERT INTO OCCASIONAL_PUSH_STACK (PUSH_TYPE, CUST_SEQ, SCHEDULE_DT, REG_DATE) VALUES ('PUSH001P', 3, DATE_FORMAT(DATE_ADD(CURRENT_TIMESTAMP, INTERVAL 5 MINUTE), '%Y%m%d%H%i%s'), CURRENT_TIMESTAMP);
INSERT INTO OCCASIONAL_PUSH_STACK (PUSH_TYPE, CUST_SEQ, SCHEDULE_DT, REG_DATE) VALUES ('PUSH001P', 4, DATE_FORMAT(DATE_ADD(CURRENT_TIMESTAMP, INTERVAL 5 MINUTE), '%Y%m%d%H%i%s'), CURRENT_TIMESTAMP);
INSERT INTO OCCASIONAL_PUSH_STACK (PUSH_TYPE, CUST_SEQ, SCHEDULE_DT, REG_DATE) VALUES ('PUSH001P', 5, DATE_FORMAT(DATE_ADD(CURRENT_TIMESTAMP, INTERVAL 5 MINUTE), '%Y%m%d%H%i%s'), CURRENT_TIMESTAMP);
COMMIT;

샘플 데이터를 넣어 봤습니다.

 

5. 입력한 데이터 확인

입력하지 않은 가상 컬럼 STD_DATE에 값이 들어가 있습니다.

6. 인덱스를 잘 타는지 확인

EXPLAIN
SELECT *
FROM OCCASIONAL_PUSH_STACK
WHERE PUSH_TYPE = 'PUSH001P'
AND CUST_SEQ = 3
AND STD_DATE = DATE_FORMAT(CURRENT_DATE, '%Y%m%d')

지정한 날짜의 인덱스를 잘 타는 것 같습니다.

 

7. PERSISTENT vs VIRTUAL

VIRTUAL 의경우 실제 데이터가 저장 되지는 않고 그때 그때 계산되는 방식입니다.

PERSISTENT(STORED)는 참조 컬럼이 저장 될 때 가상 컬럼에 실제 데이터가 저장되는 방식입니다.

디폴트는 PERSISTENT 입니다.

성능은 당연히 PERSISTENT가 우수 할 것 이고 데이터의 사이즈가 크다면 VIRTUAL이 유리 할 것 입니다.

각자의 상황에 맞는 방식을 선택 하시면 될 것 같습니다.

끝.

 

DB 데이터를 삭제하는 어플리케이션을 실행중

데이터가 많아서 1분 정도에 끝날 수 있는 Java어플리케이션을 명령을 작성하고 crontab 을 통해 1분에 한번씩 실행되도록 하는데... 혹시 어플리케이션이 1분 안에 끝나지 않으면 다음프로세스가 실행되면서 예측하지 못하는 결과가 나올 수도 있다.

스프링 스케쥴러를 쓴다면 fixedDelay 같은 옵션으로 종료되어야 실행 하도록 강제 할 수 있는데 crontab는 그렇지가 않다.

해결책으로 /usr/bin/flock 명령을 통해 프로세스 실행시 특정 파일에 락을 걸고 다음 실행시 그 파일의 락이 풀렸는지 여부에 따라 실행여부 판단을 하는 방법이 있다.

예제

* * * * * /usr/bin/flock -n /tmp/원하는명.lockfile /usr/local/command/app.sh

템프러리 폴더에 특정 파일을 만들고 flock 명령이 해당 파일의 잠금 상태를 확인해서 실행하는 개념

 

감사합니다.

+ Recent posts